summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/kodi-dev-kit
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/kodi-dev-kit
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 '')
-rw-r--r--xbmc/addons/kodi-dev-kit/.gitignore36
-rw-r--r--xbmc/addons/kodi-dev-kit/CMakeLists.txt4
-rw-r--r--xbmc/addons/kodi-dev-kit/cmake/test/abi-interface-test.cmake181
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Doxyfile2589
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/DoxygenLayout.xml207
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/General/DoxygenOnAddon.dox90
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/General/General.dox31
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_1.pngbin0 -> 47796 bytes
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_2.pngbin0 -> 36079 bytes
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-cpp.pngbin0 -> 5153 bytes
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-python.pngbin0 -> 5496 bytes
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox165
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_gui.dox96
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral.dox414
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_ControllerInput_1.jpgbin0 -> 52077 bytes
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_Lifetime_9.pngbin0 -> 402251 bytes
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_1.dox294
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_10.dox149
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_2.dox139
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_3.dox138
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_4.dox94
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_5.dox113
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_6.dox185
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_7.dox130
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_8.dox86
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_9.dox215
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_general.dox8
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_python.dox299
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Skin/skin.dox69
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/kodi-dev.pngbin0 -> 1680 bytes
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/main.txt49
-rw-r--r--xbmc/addons/kodi-dev-kit/include/NOTE9
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h1877
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/AudioEngine.h619
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/CMakeLists.txt15
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h2379
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/General.h688
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/Network.h287
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h728
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioEncoder.h514
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/CMakeLists.txt20
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h1432
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/ImageDecoder.h711
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Inputstream.h2050
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h3568
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h889
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Screensaver.h424
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h1211
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VideoCodec.h446
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Visualization.h917
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/CMakeLists.txt14
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/DemuxPacket.h12
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCodec.h11
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamConstants.h11
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCrypto.h100
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/TimingConstants.h59
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/CMakeLists.txt10
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h1277
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/CMakeLists.txt19
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/ChannelGroups.h271
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Channels.h535
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EDL.h90
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EPG.h516
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/General.h536
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/MenuHook.h130
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Providers.h195
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Recordings.h545
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Stream.h330
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Timers.h896
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/CMakeLists.txt14
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/CMakeLists.txt20
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audiodecoder.h151
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audioencoder.h74
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/game.h1235
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/imagedecoder.h450
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h708
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/CMakeLists.txt14
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/demux_packet.h117
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_codec.h152
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_constants.h59
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_crypto.h138
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/timing_constants.h42
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/peripheral.h707
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h343
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/CMakeLists.txt20
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channel_groups.h57
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channels.h108
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_defines.h77
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_edl.h65
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_epg.h657
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_general.h300
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_menu_hook.h75
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_providers.h97
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_recordings.h148
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_stream.h156
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_timers.h410
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/screensaver.h60
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/vfs.h147
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/video_codec.h268
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/visualization.h139
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon_base.h404
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/audio_engine.h312
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h322
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/general.h124
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/CMakeLists.txt13
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/CMakeLists.txt21
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/button.h33
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/edit.h77
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/fade_label.h32
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/image.h35
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/label.h30
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/progress.h30
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/radio_button.h33
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/rendering.h36
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/settings_slider.h46
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/slider.h46
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/spin.h56
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/text_box.h34
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/definitions.h78
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/CMakeLists.txt19
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/context_menu.h31
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/extended_progress.h41
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/filebrowser.h75
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/keyboard.h72
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/numeric.h52
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/ok.h35
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/progress.h43
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/select.h40
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/text_viewer.h28
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/yes_no.h48
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/general.h50
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/CMakeLists.txt10
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/action_ids.h761
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/list_item.h52
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/window.h181
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/network.h46
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/CMakeLists.txt9
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/CMakeLists.txt10
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/system.h34
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/CMakeLists.txt13
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h190
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/ListItem.h345
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/Window.h915
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Button.h166
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/CMakeLists.txt21
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Edit.h217
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/FadeLabel.h148
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Image.h112
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Label.h118
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Progress.h112
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/RadioButton.h214
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Rendering.h217
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/SettingsSlider.h314
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Slider.h326
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Spin.h416
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/TextBox.h164
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/CMakeLists.txt19
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ContextMenu.h185
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h243
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/FileBrowser.h304
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Keyboard.h405
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Numeric.h347
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/OK.h101
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Progress.h244
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Select.h270
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/TextViewer.h109
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/YesNo.h188
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/CMakeLists.txt12
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h112
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GLonDX.h395
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/Shader.h571
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/input/ActionIDs.h11
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/input/CMakeLists.txt10
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/renderHelper.h82
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/platform/CMakeLists.txt9
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/platform/android/CMakeLists.txt10
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/platform/android/System.h109
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/tools/CMakeLists.txt14
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h211
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/tools/EndTime.h215
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/tools/StringUtils.h3086
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/tools/Thread.h399
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/tools/Timer.h315
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/versions.h517
-rwxr-xr-xxbmc/addons/kodi-dev-kit/tools/code-generator/code_generator.py76
-rw-r--r--xbmc/addons/kodi-dev-kit/tools/code-generator/src/commitChanges.py91
-rw-r--r--xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt.py56
-rw-r--r--xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_allfiles.py134
-rw-r--r--xbmc/addons/kodi-dev-kit/tools/code-generator/src/helper_Log.py201
-rwxr-xr-xxbmc/addons/kodi-dev-kit/tools/debian-addon-package-test.sh141
-rwxr-xr-xxbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py190
191 files changed, 53919 insertions, 0 deletions
diff --git a/xbmc/addons/kodi-dev-kit/.gitignore b/xbmc/addons/kodi-dev-kit/.gitignore
new file mode 100644
index 0000000..0256029
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/.gitignore
@@ -0,0 +1,36 @@
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+/docs
+/build
+
+# Prevent auto generated parts
+/include/groups.dox
+/tools/code-generator/creation_log.txt
+/tools/code-generator/creation_log.txt.old
diff --git a/xbmc/addons/kodi-dev-kit/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/CMakeLists.txt
new file mode 100644
index 0000000..4b539b2
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.5)
+project(kodi-dev-kit)
+
+include(cmake/test/abi-interface-test.cmake)
diff --git a/xbmc/addons/kodi-dev-kit/cmake/test/abi-interface-test.cmake b/xbmc/addons/kodi-dev-kit/cmake/test/abi-interface-test.cmake
new file mode 100644
index 0000000..2e62034
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/cmake/test/abi-interface-test.cmake
@@ -0,0 +1,181 @@
+option(DEVKIT_TEST "To test dev-kit" TRUE)
+option(DEVKIT_TEST_CPP "To test dev-kit headers correct in \"C++\" compile" FALSE)
+option(DEVKIT_TEST_STOP_ON_ERROR "To stop build if during \"C\" ABI test an error was found" FALSE)
+
+if(NOT DEVKIT_TEST)
+ return()
+endif()
+
+include(CheckCSourceCompiles)
+include(CheckCXXSourceCompiles)
+
+list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/kodi
+ ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
+message(STATUS "################################################################################")
+message(STATUS "# Run test about dev-kit headers for correct style")
+message(STATUS "#")
+
+# Set minimal required defines
+if(CORE_SYSTEM_NAME STREQUAL android)
+ set(DEVKIT_TEST_DEFINES "\
+#define HAS_GLES 3
+#define TARGET_POSIX
+#define TARGET_LINUX
+#define TARGET_ANDROID
+")
+elseif(CORE_SYSTEM_NAME STREQUAL darwin_embedded)
+ set(DEVKIT_TEST_DEFINES "\
+#define HAS_GLES 2
+#define TARGET_POSIX
+#define TARGET_DARWIN
+#define TARGET_DARWIN_EMBEDDED
+")
+elseif(CORE_SYSTEM_NAME STREQUAL osx)
+ set(DEVKIT_TEST_DEFINES "\
+#define HAS_GL 1
+#define TARGET_DARWIN
+#define TARGET_DARWIN_OSX
+")
+elseif(CORE_SYSTEM_NAME STREQUAL windows)
+ set(DEVKIT_TEST_DEFINES "\
+#define HAS_DX 1
+#define WIN32
+#define TARGET_WINDOWS
+#define TARGET_WINDOWS_DESKTOP
+")
+elseif(CORE_SYSTEM_NAME STREQUAL linux)
+ set(DEVKIT_TEST_DEFINES "\
+#define HAS_GL 1
+#define TARGET_POSIX
+#define TARGET_LINUX
+")
+else()
+ set(DEVKIT_TEST_DEFINES "\
+#define HAS_GL 1
+#define TARGET_POSIX
+#define TARGET_FREEBSD
+")
+endif()
+
+# Read list of all available headers
+file(GLOB_RECURSE DEVKIT_HEADERS
+ include/kodi/*.h
+)
+
+##
+# Check the "C" headers itself with compile in "C"
+#
+
+message(STATUS "")
+message(STATUS "================================================================================")
+message(STATUS "Run \"C\" headers:")
+
+set(DEVKIT_HEADER_NO 0)
+foreach(DEVKIT_HEADER ${DEVKIT_HEADERS})
+ if(NOT DEVKIT_HEADER MATCHES "c-api")
+ continue()
+ endif()
+
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/include/" "" DEVKIT_HEADER_NAME ${DEVKIT_HEADER})
+
+ message(STATUS "--------------------------------------------------------------------------------")
+ message(STATUS "Checking \"C\" ABI about \"#include <${DEVKIT_HEADER_NAME}>\":")
+
+ math(EXPR DEVKIT_HEADER_NO "${DEVKIT_HEADER_NO}+1")
+ set(DEVKIT_TEST_NAME "C_TEST_BUILD_A_${DEVKIT_HEADER_NO}")
+
+ check_c_source_compiles("\
+${DEVKIT_TEST_DEFINES}
+#include \"${DEVKIT_HEADER}\"
+int main()
+{
+ return 0;
+}" ${DEVKIT_TEST_NAME})
+
+ if (NOT ${DEVKIT_TEST_NAME} EQUAL 1)
+ if(${DEVKIT_TEST_STOP_ON_ERROR})
+ message(FATAL_ERROR " - Header not match needed \"C\" ABI: \"#include <${DEVKIT_HEADER_NAME}>\" (see CMakeError.log)")
+ else()
+ message(STATUS " - WARNING: Header not match needed \"C\" ABI: \"#include <${DEVKIT_HEADER_NAME}>\" (see CMakeError.log)")
+ endif()
+ endif()
+endforeach()
+
+##
+# Check the "C++" headers itself with compile in "C"
+#
+message(STATUS "")
+message(STATUS "================================================================================")
+message(STATUS "Run \"C++\" headers (to confirm there a safe within \"C\"):")
+
+set(DEVKIT_HEADER_NO 0)
+foreach(DEVKIT_HEADER ${DEVKIT_HEADERS})
+ if(DEVKIT_HEADER MATCHES "c-api")
+ continue()
+ endif()
+
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/include/" "" DEVKIT_HEADER_NAME ${DEVKIT_HEADER})
+
+ message(STATUS "--------------------------------------------------------------------------------")
+ message(STATUS "Checking \"C\" ABI about \"#include <${DEVKIT_HEADER_NAME}>\":")
+
+ math(EXPR DEVKIT_HEADER_NO "${DEVKIT_HEADER_NO}+1")
+ set(DEVKIT_TEST_NAME "C_TEST_BUILD_B_${DEVKIT_HEADER_NO}")
+
+ check_c_source_compiles("\
+${DEVKIT_TEST_DEFINES}
+#include \"${DEVKIT_HEADER}\"
+int main()
+{
+ return 0;
+}" ${DEVKIT_TEST_NAME})
+
+ if (NOT ${DEVKIT_TEST_NAME} EQUAL 1)
+ if(${DEVKIT_TEST_STOP_ON_ERROR})
+ message(FATAL_ERROR " - \"C++\" header not safe about \"C\" ABI: \"#include <${DEVKIT_HEADER_NAME}>\" (see CMakeError.log)")
+ else()
+ message(STATUS " - WARNING: \"C++\" header not safe about \"C\" ABI: \"#include <${DEVKIT_HEADER_NAME}>\" (see CMakeError.log)")
+ endif()
+ endif()
+endforeach()
+
+##
+# Check the "C++" headers itself with compile in "C++"
+#
+if(DEVKIT_TEST_CPP)
+ message(STATUS "")
+ message(STATUS "================================================================================")
+ message(STATUS "Run \"C++\" headers (to confirm there a correct within \"C++\"):")
+
+ set(DEVKIT_HEADER_NO 0)
+ foreach(DEVKIT_HEADER ${DEVKIT_HEADERS})
+ if(DEVKIT_HEADER MATCHES "c-api")
+ continue()
+ endif()
+
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/include/" "" DEVKIT_HEADER_NAME ${DEVKIT_HEADER})
+
+ message(STATUS "--------------------------------------------------------------------------------")
+ message(STATUS "Checking \"C++\" about \"#include <${DEVKIT_HEADER_NAME}>\":")
+
+ math(EXPR DEVKIT_HEADER_NO "${DEVKIT_HEADER_NO}+1")
+ set(DEVKIT_TEST_NAME "CPP_TEST_BUILD_${DEVKIT_HEADER_NO}")
+
+ check_cxx_source_compiles("\
+${DEVKIT_TEST_DEFINES}
+#include \"${DEVKIT_HEADER}\"
+int main()
+{
+ return 0;
+}" ${DEVKIT_TEST_NAME})
+
+ if (NOT ${DEVKIT_TEST_NAME} EQUAL 1)
+ if(${DEVKIT_TEST_STOP_ON_ERROR})
+ message(FATAL_ERROR " - \"C++\" header failed to build: \"#include <${DEVKIT_HEADER_NAME}>\" (see CMakeError.log)")
+ else()
+ message(STATUS " - \"C++\" header failed to build: \"#include <${DEVKIT_HEADER_NAME}>\" (see CMakeError.log)")
+ endif()
+ endif()
+ endforeach()
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Doxyfile b/xbmc/addons/kodi-dev-kit/doxygen/Doxyfile
new file mode 100644
index 0000000..eea8a58
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Doxyfile
@@ -0,0 +1,2589 @@
+# Doxyfile 1.8.13
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+# This includes a own file where used on Kodi itself and by kodi-dev-kit.
+# Also used to have on new releases better overview which parts need update.
+@INCLUDE = ../../../../docs/doxygen/kodi_values.doxy
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "Kodi Development"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+# PROJECT_NUMBER done by ./kodi_values.doxy
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF = "for Binary and Script based Add-Ons"
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO = ./kodi-dev.png
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ../docs
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH = .
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+# ALIASES done by ./kodi_values.doxy
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = YES
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = YES
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = YES
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = YES
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = YES
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = YES
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE = DoxygenLayout.xml
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = main.txt \
+ General/General.dox \
+ General/DoxygenOnAddon.dox \
+ ../../../GUIInfoManager.cpp \
+ Modules/modules_general.dox \
+ Modules/modules_cpp.dox \
+ Modules/modules_cpp_gui.dox \
+ Modules/modules_cpp_peripheral.dox \
+ Modules/modules_python.dox \
+ Skin/skin.dox \
+ ../../../../cmake/scripts/common/AddonHelpers.dox \
+ ../../../cores/RetroPlayer/guicontrols/GUIGameControl.dox \
+ ../../../pvr/guilib/GUIEPGGridContainer.dox \
+ ../../../guilib/GUIButtonControl.dox \
+ ../../../guilib/GUIColorButtonControl.dox \
+ ../../../guilib/GUIControlGroup.dox \
+ ../../../guilib/GUIEditControl.dox \
+ ../../../guilib/GUIFadeLabelControl.dox \
+ ../../../guilib/GUIFixedListContainer.dox \
+ ../../../guilib/GUIImage.dox \
+ ../../../guilib/GUILabelControl.dox \
+ ../../../guilib/GUIListContainer.dox \
+ ../../../guilib/GUIListGroup.dox \
+ ../../../guilib/GUIMoverControl.dox \
+ ../../../guilib/GUIMultiImage.dox \
+ ../../../guilib/GUIPanelContainer.dox \
+ ../../../guilib/GUIProgressControl.dox \
+ ../../../guilib/GUIRadioButtonControl.dox \
+ ../../../guilib/GUIRangesControl.dox \
+ ../../../guilib/GUIRenderingControl.dox \
+ ../../../guilib/GUIResizeControl.dox \
+ ../../../guilib/GUIRSSControl.dox \
+ ../../../guilib/GUIScrollBarControl.dox \
+ ../../../guilib/GUISettingsSliderControl.dox \
+ ../../../guilib/GUISliderControl.dox \
+ ../../../guilib/GUISpinControl.dox \
+ ../../../guilib/GUISpinControlEx.dox \
+ ../../../guilib/GUITextBox.dox \
+ ../../../guilib/GUIToggleButtonControl.dox \
+ ../../../guilib/GUIVideoControl.dox \
+ ../../../guilib/GUIVisualisationControl.dox \
+ ../../../guilib/GUIWrappingListContainer.dox \
+ ../../../guilib/WindowIDs.dox \
+ ../../../guilib/_Controls.dox \
+ ../../../interfaces/builtins/AddonBuiltins.cpp \
+ ../../../interfaces/builtins/AndroidBuiltins.cpp \
+ ../../../interfaces/builtins/ApplicationBuiltins.cpp \
+ ../../../interfaces/builtins/CECBuiltins.cpp \
+ ../../../interfaces/builtins/GUIBuiltins.cpp \
+ ../../../interfaces/builtins/GUIContainerBuiltins.cpp \
+ ../../../interfaces/builtins/GUIControlBuiltins.cpp \
+ ../../../interfaces/builtins/LibraryBuiltins.cpp \
+ ../../../interfaces/builtins/OpticalBuiltins.cpp \
+ ../../../interfaces/builtins/PictureBuiltins.cpp \
+ ../../../interfaces/builtins/PlayerBuiltins.cpp \
+ ../../../interfaces/builtins/ProfileBuiltins.cpp \
+ ../../../interfaces/builtins/PVRBuiltins.cpp \
+ ../../../interfaces/builtins/SkinBuiltins.cpp \
+ ../../../interfaces/builtins/SystemBuiltins.cpp \
+ ../../../interfaces/builtins/WeatherBuiltins.cpp \
+ ../../../interfaces/legacy/Addon.h \
+ ../../../interfaces/legacy/Control.h \
+ ../../../interfaces/legacy/Dialog.h \
+ ../../../interfaces/legacy/DrmCryptoSession.h \
+ ../../../interfaces/legacy/File.h \
+ ../../../interfaces/legacy/InfoTagGame.h \
+ ../../../interfaces/legacy/InfoTagMusic.h \
+ ../../../interfaces/legacy/InfoTagPicture.h \
+ ../../../interfaces/legacy/InfoTagRadioRDS.h \
+ ../../../interfaces/legacy/InfoTagVideo.h \
+ ../../../interfaces/legacy/Keyboard.h \
+ ../../../interfaces/legacy/ListItem.h \
+ ../../../interfaces/legacy/ModuleXbmcgui.h \
+ ../../../interfaces/legacy/ModuleXbmc.h \
+ ../../../interfaces/legacy/ModuleXbmcplugin.h \
+ ../../../interfaces/legacy/ModuleXbmcvfs.h \
+ ../../../interfaces/legacy/Monitor.h \
+ ../../../interfaces/legacy/Player.h \
+ ../../../interfaces/legacy/PlayList.h \
+ ../../../interfaces/legacy/RenderCapture.h \
+ ../../../interfaces/legacy/Settings.h \
+ ../../../interfaces/legacy/Stat.h \
+ ../../../interfaces/legacy/WindowDialog.h \
+ ../../../interfaces/legacy/Window.h \
+ ../../../interfaces/legacy/WindowXML.h \
+ ../../../interfaces/legacy/wsgi/WsgiErrorStream.h \
+ ../../../interfaces/legacy/wsgi/WsgiInputStream.h \
+ ../../../interfaces/legacy/wsgi/WsgiResponseBody.h \
+ ../../../interfaces/legacy/wsgi/WsgiResponse.h \
+ ../../../pictures/PictureInfoTag.cpp \
+ ../include
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.idl \
+ *.ddl \
+ *.odl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.cs \
+ *.d \
+ *.php \
+ *.php4 \
+ *.php5 \
+ *.phtml \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.for \
+ *.tcl \
+ *.vhd \
+ *.vhdl \
+ *.ucf \
+ *.qsf \
+ *.as \
+ *.js \
+ *.GPL
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH = .
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH = .
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES = LICENSE.md
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 30
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 350
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \
+ DOXYGEN_SHOULD_USE_THIS \
+ __cplusplus
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: YES.
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
+# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
+# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = svg
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = YES
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/DoxygenLayout.xml b/xbmc/addons/kodi-dev-kit/doxygen/DoxygenLayout.xml
new file mode 100644
index 0000000..a1f0c67
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/DoxygenLayout.xml
@@ -0,0 +1,207 @@
+<doxygenlayout version="1.0">
+ <!-- Generated by doxygen 1.8.9.1 -->
+ <!-- Navigation index tabs for HTML output -->
+ <navindex>
+ <tab type="mainpage" visible="yes" title=""/>
+ <tab type="pages" visible="yes" title="" intro=""/>
+ <tab type="modules" visible="yes" title="Language Development" intro=""/>
+<!-- <tab type="namespaces" visible="yes" title="">
+ <tab type="namespacelist" visible="yes" title="" intro=""/>
+ <tab type="namespacemembers" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="classes" visible="yes" title="">
+ <tab type="classlist" visible="yes" title="" intro=""/>
+ <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+ <tab type="hierarchy" visible="yes" title="" intro=""/>
+ <tab type="classmembers" visible="yes" title="" intro=""/>
+ </tab>-->
+ <tab type="files" visible="yes" title="">
+ <tab type="filelist" visible="yes" title="" intro=""/>
+ <tab type="globals" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="examples" visible="yes" title="" intro=""/>
+ <tab type="usergroup" title="Older versions">
+ <tab type="user" url="http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/" title="Kodi 16.x Jarvis"/>
+ <tab type="user" url="http://mirrors.kodi.tv/docs/python-docs/15.x-isengard/" title="Kodi 15.x Isengard"/>
+ <tab type="user" url="http://mirrors.kodi.tv/docs/python-docs/14.x-helix/" title="Kodi 14.x Helix"/>
+ <tab type="user" url="http://mirrors.kodi.tv/docs/python-docs/13.0-gotham/" title="XBMC 13.x Gotham"/>
+ <tab type="user" url="http://mirrors.kodi.tv/docs/python-docs/12.2-frodo/" title="XBMC 12.x Frodo"/>
+ </tab>
+ </navindex>
+
+ <!-- Layout definition for a class page -->
+ <class>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <includes visible="$SHOW_INCLUDE_FILES"/>
+ <inheritancegraph visible="$CLASS_GRAPH"/>
+ <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+ <memberdecl>
+ <nestedclasses visible="yes" title=""/>
+ <publictypes title=""/>
+ <services title=""/>
+ <interfaces title=""/>
+ <publicslots title=""/>
+ <signals title=""/>
+ <publicmethods title=""/>
+ <publicstaticmethods title=""/>
+ <publicattributes title=""/>
+ <publicstaticattributes title=""/>
+ <protectedtypes title=""/>
+ <protectedslots title=""/>
+ <protectedmethods title=""/>
+ <protectedstaticmethods title=""/>
+ <protectedattributes title=""/>
+ <protectedstaticattributes title=""/>
+ <packagetypes title=""/>
+ <packagemethods title=""/>
+ <packagestaticmethods title=""/>
+ <packageattributes title=""/>
+ <packagestaticattributes title=""/>
+ <properties title=""/>
+ <events title=""/>
+ <privatetypes title=""/>
+ <privateslots title=""/>
+ <privatemethods title=""/>
+ <privatestaticmethods title=""/>
+ <privateattributes title=""/>
+ <privatestaticattributes title=""/>
+ <friends title=""/>
+ <related title="" subtitle=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+<!-- <detaileddescription title=""/> -->
+ <memberdef>
+ <inlineclasses title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <services title=""/>
+ <interfaces title=""/>
+ <constructors title=""/>
+ <functions title=""/>
+ <related title=""/>
+ <variables title=""/>
+ <properties title=""/>
+ <events title=""/>
+ </memberdef>
+ <allmemberslink visible="yes"/>
+ <usedfiles visible="$SHOW_USED_FILES"/>
+ <authorsection visible="yes"/>
+ </class>
+
+ <!-- Layout definition for a namespace page -->
+ <namespace>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <memberdecl>
+ <nestednamespaces visible="yes" title=""/>
+ <constantgroups visible="yes" title=""/>
+ <classes visible="yes" title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+<!-- <detaileddescription title=""/> -->
+ <memberdef>
+ <inlineclasses title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ </memberdef>
+ <authorsection visible="yes"/>
+ </namespace>
+
+ <!-- Layout definition for a file page -->
+ <file>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <includes visible="$SHOW_INCLUDE_FILES"/>
+ <includegraph visible="$INCLUDE_GRAPH"/>
+ <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+ <sourcelink visible="yes"/>
+ <memberdecl>
+ <classes visible="yes" title=""/>
+ <namespaces visible="yes" title=""/>
+ <constantgroups visible="yes" title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+<!-- <detaileddescription title=""/> -->
+ <memberdef>
+ <inlineclasses title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ </memberdef>
+ <authorsection/>
+ </file>
+
+ <!-- Layout definition for a group page -->
+ <group>
+<!-- <briefdescription visible="yes"/> -->
+ <detaileddescription title=""/>
+ <groupgraph visible="$GROUP_GRAPHS"/>
+ <memberdecl>
+ <nestedgroups visible="yes" title=""/>
+ <dirs visible="yes" title=""/>
+ <files visible="yes" title=""/>
+ <namespaces visible="yes" title=""/>
+<!-- <classes visible="yes" title=""/> -->
+<!-- <defines title=""/> -->
+ <typedefs title=""/>
+<!-- <enums title=""/> -->
+ <enumvalues title=""/>
+<!-- <functions title=""/> -->
+ <variables title=""/>
+ <signals title=""/>
+ <publicslots title=""/>
+ <protectedslots title=""/>
+ <privateslots title=""/>
+ <events title=""/>
+ <properties title=""/>
+ <friends title=""/>
+<!-- <membergroups visible="yes"/>-->
+ </memberdecl>
+<!-- <detaileddescription title=""/> -->
+ <memberdef>
+ <pagedocs/>
+ <inlineclasses title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <enumvalues title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ <signals title=""/>
+ <publicslots title=""/>
+ <protectedslots title=""/>
+ <privateslots title=""/>
+ <events title=""/>
+ <properties title=""/>
+ <friends title=""/>
+ </memberdef>
+ <authorsection visible="yes"/>
+ </group>
+
+ <!-- Layout definition for a directory page -->
+ <directory>
+ <briefdescription visible="yes"/>
+ <directorygraph visible="yes"/>
+ <detaileddescription title=""/>
+ <memberdecl>
+ <dirs visible="yes"/>
+ <files visible="yes"/>
+ </memberdecl>
+<!-- <detaileddescription title=""/> -->
+ </directory>
+
+</doxygenlayout>
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/General/DoxygenOnAddon.dox b/xbmc/addons/kodi-dev-kit/doxygen/General/DoxygenOnAddon.dox
new file mode 100644
index 0000000..29fa6ee
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/General/DoxygenOnAddon.dox
@@ -0,0 +1,90 @@
+/*!
+
+@page Doxygen_On_Addon Doxygen on Kodi's Add-On headers
+
+### This page is for notes on using Doxygen to document the Kodi's Add-On headers source code.
+
+[Doxygen](http://www.stack.nl/~dimitri/doxygen/index.html), is a documentation
+system for C++, C, Java, and some other weird languages. It can generate html
+docs documenting a projects source code, by either extracting special tags from
+the source code (put there by people wanting to make use of doxygen), or doxygen
+attempts to build documentation from existing source.
+
+Doxygen seems to be installed on the NMR systems, type:
+~~~~~~~~~~~~~
+doxygen --version
+~~~~~~~~~~~~~
+
+
+_ _ _
+
+Start doxygen documentation for add-ons always with `///` and on Kodi itself with `/*!`, this makes it more easy to see for which place the documentation is.
+
+<b>Here an example on add-on about function coding style:</b>
+
+\verbatim
+#ifdef DOXYGEN_SHOULD_USE_THIS
+ ///
+ /// \ingroup python_xbmcgui_window
+ /// @brief Sets the resolution
+ ///
+ /// That the coordinates of all controls are defined in. Allows Kodi
+ /// to scale control positions and width/heights to whatever resolution
+ /// Kodi is currently using.
+ ///
+ /// @param[in] res Coordinate resolution to set
+ /// Resolution is one of the following:
+ /// | value | Resolution |
+ /// |:-----:|:--------------------------|
+ /// | 0 | 1080i (1920x1080)
+ /// | 1 | 720p (1280x720)
+ /// | 2 | 480p 4:3 (720x480)
+ /// | 3 | 480p 16:9 (720x480)
+ /// | 4 | NTSC 4:3 (720x480)
+ /// | 5 | NTSC 16:9 (720x480)
+ /// | 6 | PAL 4:3 (720x576)
+ /// | 7 | PAL 16:9 (720x576)
+ /// | 8 | PAL60 4:3 (720x480)
+ /// | 9 | PAL60 16:9 (720x480)
+ /// @return Nothing only added as example here :)
+ /// @param[out] nothingExample Example here, if on value pointer data becomes
+ /// returned.
+ /// @throws TypeError If supplied argument is not of List type, or a
+ /// control is not of Control type
+ /// @throws ReferenceError If control is already used in another window
+ /// @throws RuntimeError Should not happen :-)
+ ///
+ ///
+ ///--------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.py}
+ /// ..
+ /// win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
+ /// win.setCoordinateResolution(0)
+ /// ..
+ /// ~~~~~~~~~~~~~
+ ///
+ setCoordinateResolution(...);
+#else
+ SWIGHIDDENVIRTUAL bool setCoordinateResolution(long res, int &nothingExample);
+#endif
+\endverbatim
+- \verbatim /// \ingroup\endverbatim - Define the group where the documentation part comes in.
+- \verbatim /// @brief\endverbatim - Add a small text of part there.
+- \verbatim /// TEXT_FIELD\endverbatim - Add a bigger text there if needed.
+- \verbatim /// @param[in] VALUE_NAME VALUE_TEXT\endverbatim - To set input parameter defined by name and add a description. There the example also add a small table which is useful to describe values.
+- \verbatim /// @param[out] VALUE_NAME VALUE_TEXT\endverbatim - To set output parameter defined by name and add a description.
+- \verbatim /// @return VALUE_TEXT\endverbatim - To add a description of return value.
+- \verbatim /// @throws ERROR_TYPE ERROR_TEXT\endverbatim - If also exception becomes handled, can you use this for description.
+- \verbatim /// TEXT_FIELD\endverbatim - Add a much bigger text there if needed.
+- \verbatim /// ------------------\endverbatim - Use this to define a field line, e.g. if you add example add this always before, further must you make two empty lines before to prevent add of them on string before!
+- \verbatim /// ~~~~~~~~~~~~~ \endverbatim - Here can you define a code example which must start and end with the definition string, also can you define the code style with e.g. <b>{.py}</b> for Python or <b>{.cpp}</b> for CPP code on the first line of them.
+
+@note Start all `VALUE_TEXT` at same character to hold a clean code on <c>*.cpp</c> or <c>*.h</c> files.\n\n
+ The `#ifdef DOXYGEN_SHOULD_USE_THIS` on example above can be becomes used
+ if for Doxygen another function is needed to describe.
+
+If you want to prevent a part from doxygen can you define <b>`#ifndef DOXYGEN_SHOULD_SKIP_THIS`</b>
+or <b>`#ifdef DOXYGEN_SHOULD_USE_THIS`</b> on the related code.
+*/
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/General/General.dox b/xbmc/addons/kodi-dev-kit/doxygen/General/General.dox
new file mode 100644
index 0000000..9862eb6
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/General/General.dox
@@ -0,0 +1,31 @@
+/*!
+
+\page general General
+\brief \doc_header{ General descriptions }
+
+The used code guidelines from Kodi
+@note Is not direct needed on C++ add-ons but makes it more easy for reviews and
+changes from the others.
+
+\subpage code_guidelines
+
+--------------------------------------------------------------------------------
+
+Guideline for Kodi's developers to create documentation
+
+\subpage Doxygen_On_Addon
+
+*/
+
+---------------------------------------------------------------------------------
+
+@subpage revisions "Revisions against older versions"
+*/
+
+/*!
+\page revisions Revisions
+
+\subpage python_revisions
+
+\subpage skinning_revisions
+*/ \ No newline at end of file
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_1.png b/xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_1.png
new file mode 100644
index 0000000..46f9b8c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_1.png
Binary files differ
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_2.png b/xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_2.png
new file mode 100644
index 0000000..7af0abf
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/cpp_kodi_addon_vfs_protocol_2.png
Binary files differ
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-cpp.png b/xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-cpp.png
new file mode 100644
index 0000000..870065e
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-cpp.png
Binary files differ
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-python.png b/xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-python.png
new file mode 100644
index 0000000..179a2ae
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/logo-python.png
Binary files differ
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox
new file mode 100644
index 0000000..0967bdd
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox
@@ -0,0 +1,165 @@
+/*!
+
+\defgroup cpp C++
+\image html logo-cpp.png
+\brief \htmlonly
+ <h3><span style="text-decoration: underline;"><span style="font-style: italic;"><span
+ style="color: rgb(102, 102, 102);">C++ Binary Add-On Development</span></span></span></h3>
+ \endhtmlonly
+
+Kodi allows the use of **C++** addons to expand their possibilities. This gives you
+many options to expand it quickly and easily with new features.
+
+Here is a table of the types currently possible:
+\table_start
+ \table_h3{ Type, Class, Description }
+ \table_row3{ <b>Audio decoder</b>,
+ @ref cpp_kodi_addon_audiodecoder "kodi::addon::CInstanceAudioDecoder",
+ For audio decoders as binary add-ons. This class implements a way to handle
+ special types of audio files.
+ }
+ \table_row3{ <b>Audio encoder</b>,
+ @ref cpp_kodi_addon_audioencoder "kodi::addon::CInstanceAudioEncoder",
+ To convert audio data\, such as a CD\, to a new format and create files for this.
+ }
+ \table_row3{ <b>Game engine</b>,
+ @ref cpp_kodi_addon_game "kodi::addon::CInstanceGame",
+ This is to provide support for games in the system.
+ }
+ \table_row3{ <b>Image decoder</b>,
+ @ref cpp_kodi_addon_imagedecoder "kodi::addon::CInstanceImageDecoder",
+ This instance type is used to allow Kodi various additional image format types.
+ }
+ \table_row3{ <b>Inputstream</b>,
+ @ref cpp_kodi_addon_inputstream "kodi::addon::CInstanceInputStream",
+ To process special video and/or audio streams. This allows addons to support newer species in Kodi.
+ }
+ \table_row3{ <b>Peripheral</b>,
+ @ref cpp_kodi_addon_peripheral "kodi::addon::CInstancePeripheral",
+ Made to have Kodi controllable with new and different ways\, such as Joystick.
+ }
+ \table_row3{ <b>Screensaver</b>,
+ @ref cpp_kodi_addon_screensaver "kodi::addon::CInstanceScreensaver",
+ A screensaver is a Kodi addon that fills the screen with moving images or
+ patterns when the computer is not in use.
+ }
+ \table_row3{ <b>PVR (TV / radio handling)</b>,
+ @ref cpp_kodi_addon_pvr "kodi::addon::CInstancePVRClient",
+ Used to provide Kodi with various sources for TV and radio streams.
+ }
+ \table_row3{ <b>VFS (Virtual filesystem support)</b>,
+ @ref cpp_kodi_addon_vfs "kodi::addon::CInstanceVFS",
+ This instance type is used to allow Kodi various additional file system types.
+ }
+ \table_row3{ <b>Video codec</b>,
+ @ref cpp_kodi_addon_videocodec "kodi::addon::CInstanceVideoCodec",
+ Used to decode special video formats and make them usable for playback.
+ @note This can only be used in connection with @ref cpp_kodi_addon_inputstream "kodi::addon::CInstanceInputStream".
+ }
+ \table_row3{ <b>Visualization</b>,
+ @ref cpp_kodi_addon_visualization "kodi::addon::CInstanceVisualization",
+ Music visualization is a feature in Kodi that generates animated imagery based on a piece of music.
+ }
+\table_end
+*/
+/*!
+\defgroup cpp_cmake CMake addon creation structure
+\ingroup cpp
+\brief **CMake help macros to create addon for Kodi**
+*/
+/*!
+\defgroup cpp_kodi Interface - kodi
+\ingroup cpp
+\brief **General addon interface functions**
+*/
+ /*!
+ \defgroup cpp_kodi_Defs Definitions, structures and enumerators
+ \ingroup cpp_kodi
+ @brief **General definition values**
+ */
+/*!
+\defgroup cpp_kodi_addon Interface - kodi::addon
+\ingroup cpp
+\brief **Addon type interface functions and classes**
+*/
+ /*!
+ \defgroup cpp_kodi_addon_addonbase class CAddonBase
+ \ingroup cpp_kodi_addon
+ */
+ /*!
+ \defgroup cpp_kodi_addon_addonbase_Defs Definitions, structures and enumerators
+ \ingroup cpp_kodi_addon_addonbase
+ @brief **General definition values**
+ */
+ /*!
+ \defgroup cpp_kodi_addon_instances Addon type instances
+ \brief **Group of possible processing instances which can be made available by an add-on**\n
+ Kodi enables numerous different ways in which the necessary documentation is included in this group.
+ \ingroup cpp_kodi_addon
+ */
+ /*!
+ \defgroup cpp_kodi_addon_audiodecoder Audio Decoder
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_audioencoder Audio Encoder
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_game Game
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_imagedecoder Image Decoder
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_inputstream Inputstream
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_peripheral Peripheral
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_pvr PVR
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_screensaver Screensaver
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_vfs VFS
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_videocodec Video Codec
+ \ingroup cpp_kodi_addon_instances
+ */
+ /*!
+ \defgroup cpp_kodi_addon_visualization Visualization
+ \ingroup cpp_kodi_addon_instances
+ */
+/*!
+\defgroup cpp_kodi_gui Interface - kodi::gui
+\ingroup cpp
+\brief **Graphical functions for Windows and Dialogs to show**\n
+Offers classes and functions that manipulate the Graphical User Interface
+through windows, dialogs, and various control widgets.
+*/
+/*!
+\defgroup cpp_kodi_platform Interface - kodi::platform
+\ingroup cpp
+\brief **Platform specific functions**\n
+This group contains OS platform specific functions with which Kodi is accessed.
+
+@note Its header and its classes and functions are only available in the
+associated OS and are not available outside.
+*/
+/*!
+\defgroup cpp_kodi_tools Interface - kodi::tools
+\ingroup cpp
+\brief **Helper tools and functions**\n
+This group includes things that only work indirectly with Kodi.
+*/
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_gui.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_gui.dox
new file mode 100644
index 0000000..4950766
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_gui.dox
@@ -0,0 +1,96 @@
+/*!
+@defgroup cpp_kodi_gui_Defs Definitions, structures and enumerators
+@ingroup cpp_kodi_gui
+@brief **GUI add-on interface definition values**\n
+All GUI functions associated data structures.
+
+Used to exchange the available options between Kodi and addon.\n
+The groups described here correspond to the groups of functions on GUI.
+*/
+
+
+/*!
+@defgroup cpp_kodi_gui_general 1. General
+@ingroup cpp_kodi_gui
+@brief **General GUI related functions**\n
+This includes independent functions which can be used by different locations and
+called up independently.
+
+*/
+
+/*!
+@defgroup cpp_kodi_gui_dialogs 2. Dialogs
+@ingroup cpp_kodi_gui
+@brief **Different GUI dialog for user queries**\n
+This is where the individual dialogs possible for addons are carried out, with
+which any user access can be given, e.g. Yes/No dialog.
+
+
+*/
+
+/*!
+@defgroup cpp_kodi_gui_windows 3. Windows
+@ingroup cpp_kodi_gui
+@brief **Classes and data for displaying a window in Kodi**\n
+This group contains the primary class @ref cpp_kodi_gui_windows_window "kodi::gui::CWindow"
+and also various subclasses belonging to it (various controls, list item).
+
+Kodi is noted as having a very flexible and robust framework for its GUI,
+making theme-skinning and personal customization very accessible. Users
+can create their own skin (or modify an existing skin) and share it with
+others.
+
+This class is used to process the display of a window in Kodi from the addon.
+
+The addon can process the controls stored in the XML and lists displayed in the
+GUI, set values and manage user access.
+
+*/
+
+/*!
+@defgroup cpp_kodi_gui_windows_window 1. GUI window (kodi::gui::CWindow)
+@ingroup cpp_kodi_gui_windows
+*/
+
+/*!
+@defgroup cpp_kodi_gui_windows_listitem 2. GUI list item (kodi::gui::CListItem)
+@ingroup cpp_kodi_gui_windows
+*/
+
+/*!
+@defgroup cpp_kodi_gui_windows_controls 3. GUI controls (kodi::gui::controls::C...)
+@ingroup cpp_kodi_gui_windows
+@brief @cpp_namespace{ kodi::gui::controls }
+<b>GUI control elements</b>\n
+This group contains classes which are used in @ref cpp_kodi_gui_windows_window "kodi::gui::CWindow"
+to edit associated skin control elements, be it to set or get their values, or
+to make them visible or hidden.
+
+See @ref skin_parts for a detailed description of the skin XML parts accessed
+from here.
+
+In order to access a control in skin XML using an add-on, it must have an id,
+otherwise an add-on cannot access it.
+
+~~~~~~~~~~~~~~~xml
+ <control type="..." id="1"> <!-- Id's defined here to use on addon -->
+ ...
+ </control>
+~~~~~~~~~~~~~~~
+
+@note These classes from here can only be used together with the associated
+window and cannot be used independently.
+
+
+*/
+
+
+/*!
+@defgroup cpp_kodi_gui_helpers 4. Helpers
+@ingroup cpp_kodi_gui
+@brief **Auxiliary classes for processing the GUI within the addon**\n
+The auxiliary functions and classes stored here only work indirectly with Kodi
+and are mostly only intended to simplify an add-on development.
+
+
+*/
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral.dox
new file mode 100644
index 0000000..dfc2b0a
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral.dox
@@ -0,0 +1,414 @@
+/*!
+
+@defgroup cpp_kodi_addon_peripheral_Docs Peripheral system
+@ingroup cpp_kodi_addon_peripheral
+@brief System description
+
+*/
+
+//------------------------------------------------------------------------------
+
+
+/*!
+
+@defgroup cpp_kodi_addon_peripheral_Docs_ControllerInput Controller Input
+@ingroup cpp_kodi_addon_peripheral_Docs
+@brief Controller Input for Emulator Development
+
+# Introduction
+
+Input can come from many types of peripherals such as controllers, arcade cabinets, keyboards and remotes. However, the emulator needs to emulate the peripherals of its game platform. For example, NES emulators can emulate controllers, light guns and flight simulator joysticks. This system translates input from hardware peripherals to emulated ones.
+
+## Table of contents
+
+1. @ref cpp_kodi_addon_peripheral_Docs_ControllerInput_Profiles "Controller profiles"
+2. @ref cpp_kodi_addon_peripheral_Docs_ControllerInput_JoystickDrivers "Joystick drivers"
+3. @ref cpp_kodi_addon_peripheral_Docs_ControllerInput_ButtonMaps "Button maps"
+4. @ref cpp_kodi_addon_peripheral_Docs_ControllerInput_JoystickDriverFuckery "Joystick driver fuckery"
+
+*/
+
+/*!
+
+@defgroup cpp_kodi_addon_peripheral_Docs_ControllerInput_Profiles 1. Controller profiles
+@ingroup cpp_kodi_addon_peripheral_Docs_ControllerInput
+
+# 1. Controller profiles
+
+<img src="modules_cpp_peripheral_Docs_ControllerInput_1.jpg" width="100%">
+
+Each emulated peripheral has a profile describing its input. Controller is a generic word for these peripherals, and this is the name shown in the GUI.
+
+Each controller has parts that generate input, like buttons, keys, triggers, analog sticks and accelerometers. These parts are called features of the controller.
+
+Features generate input in several different ways. For example, a button is either 1 or 0. Analog sticks, on the other hand, have two degrees of freedom. They contain two values that can range from -1.0 (fully down/left) to 1.0 (fully up/right).
+
+Features can also receive input. Rumble motors and other haptic parts accept digital or analog input.
+
+Features are grouped by the type of input they generate/accept. For example:
+
+<i>Scalar features</i>
+- Regular buttons generate a single number (either 0 or 1), so these are called scalar features.
+- Likewise, triggers and pressure-sensitive buttons generate a single number (analog value between 0.0 and 1.0, inclusive). These are also called scalar features.
+- For simplicity, keys are considered buttons
+- D-pads, also called hats, are treated as four buttons, so they result in four scalar features.
+
+<i>Vector features</i>
+- Analog sticks generate two analog values, so these are called vector features.
+- Likewise, accelerometers have an X, Y and Z axis and are also called vector features.
+
+<i>Haptic features</i>
+- Motors are technically scalar features, but because they accept input instead of generating it, they're usually processed in a different part of the code. For clarity, they are just called haptic features.
+
+*/
+
+/*!
+
+@defgroup cpp_kodi_addon_peripheral_Docs_ControllerInput_JoystickDrivers 2. Joystick drivers
+@ingroup cpp_kodi_addon_peripheral_Docs_ControllerInput
+
+# 2. Joystick drivers
+
+Unfortunately, none of the input provided by any joystick driver has information about the kind of features it belongs to. Drivers simply provide a long list of values. Generally, these are bools or floats, but some interfaces use enums, like the directions on a d-pad.
+
+To connect this information to the features of a controller profile, it is split into elements that better translate to controller features. These elements are called driver primitives.
+
+## 2.1. Types of driver primitives
+
+Buttons
+
+Consider a bool reported by the driver. This probably belongs to something that can be pressed, so it's called a button. A bool can't belong to multiple features, so it is a driver primitive.
+
+<i>Hat directions</i>
+
+Some drivers use enums or bit flags to report hat presses. In Kodi, hats are treated like four separate buttons for simplicity. Hat enums can belong to four features, so they contain four driver primitives, one for each direction.
+
+<i>Semiaxis directions</i>
+
+A float is a little trickier. The immediate assumption is an axis of an analog stick or accelerometer. However, in DirectInput, triggers are combined into a single float. Therefore, a float can map to two features, so each half of the axis (called a semiaxis) is a driver primitive.
+
+This has interesting implications. An analog stick has two axes, which is four driver primitives. Each semiaxis can map to a different feature, so the analog stick is able to emulate the four buttons of a d-pad, or the N64's C buttons.
+
+*/
+
+/*!
+
+@defgroup cpp_kodi_addon_peripheral_Docs_ControllerInput_ButtonMaps 3. Button maps
+@ingroup cpp_kodi_addon_peripheral_Docs_ControllerInput
+
+# 3. Button maps
+
+Now we return to controller profiles. Each emulator requires its own set of controllers, each with their list of features. These are mapped to the underlying driver primitives provided by the joystick driver using a button map.
+
+In the code, the button map is abstracted away behind a button map interface. This additional abstraction adds some code, but it allows button maps to be managed by an add-on.
+
+The current add-on for button maps, [peripheral.joystick](https://github.com/kodi-game/peripheral.joystick), can only recite button maps it has been given. However, it could be made smarter by using existing button map data. For example, if the add-on knows the most popular way to map a 360 controller to a SNES controller, it can generate a SNES button map knowing only the 360 one.
+
+*/
+
+/*!
+
+@defgroup cpp_kodi_addon_peripheral_Docs_ControllerInput_JoystickDriverFuckery 4. Joystick driver fuckery
+@ingroup cpp_kodi_addon_peripheral_Docs_ControllerInput
+
+# 4. Joystick driver fuckery
+
+Of course, joystick drivers have many quirks that greatly complicate things. So much so that they deserve their own chapter. Here's a list of some of the quirks I've encountered:
+
+### Combined triggers
+
+DirectInput combines left and right triggers into a single axis. They are combined using the strategy in Chapter 4: Dimension Reduction.
+
+Kodi solves this by splitting the axis into two semiaxes, as explained in Chapter 2: Joystick drivers. Each semiaxis is mapped to its own trigger.
+
+### Anomalous triggers
+
+Not all triggers start at 0.0 and travel to 1.0 (or -1.0 in DirectInput). Some triggers start at 1.0 or -1.0, and travel to 0.0 or to the opposite unit. These are called <i>anomalous triggers</i>. These triggers have two properties:
+Center - The theory here is that initial perturbations are minimal. This means that the center is determined by rounding the first value to the closest int.
+Range - The range can be half range (assumed) or full range (detected when a value has the opposite sign)
+
+### Discrete D-pads
+
+Instead of four buttons or a hat enum, D-pads can sometimes be reported as floats that use the discrete values -1.0, 0.0 and 1.0. Fortunately, because analog sticks can emulate D-pads, we can simply treat the discrete D-pad as an analog stick.
+
+### Repeated input
+
+Some buttons generate two input events. For example, some hats operate as four digital buttons AND as a discrete D-pad. This is solved via a "cooldown" while mapping, which ignores any input for around 50ms after a button is mapped.
+
+### Hat enums
+
+I consider hat enums a quirk because it just makes so much more sense to represent them using four buttons. It doesn't even guarantee mutual exclusion between opposite directions, as this can be violated by a flag with the improper bits set.
+
+### Pressure-sensitive buttons
+
+Pressure-sensitive buttons can be reported as an analog axis instead of a digital value.
+
+### Incomplete information
+
+Pertinent info (name, USB VID and PID, etc) might be missing, making it hard to identify the correct button map.
+
+*/
+
+//------------------------------------------------------------------------------
+
+/*!
+
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime Lifetime of a button press
+@ingroup cpp_kodi_addon_peripheral_Docs
+@brief The lifetime of a button press for peripherals with input
+
+# Introduction
+
+@note This documentation assumes you have the source code for Kodi and <b>peripheral.joystick</b> open in front of you. The fixed-width font is the class or struct you should reference.
+
+When a controller is plugged in and a button is pressed, it starts a large chain reaction of different systems. The button's journey is destined to reach one or more eventual outcomes:
+- An emulator / game add-on
+- Kodi's input system
+- A configuration utility
+
+Game input
+----------------
+
+Instead of being forced to use a single controller abstraction, game add-ons can request input in the form of any platform controller known to Kodi. For example, a NES emulator receives input events for a NES controller; if the emulator doesn't care, it receives events for a default 360-style controller.
+
+Kodi's input system
+----------------
+
+If no game is receiving input in fullscreen mode, the button is translated to the default 360-style controller and Kodi's keymapping system takes over from here
+
+Configuration utilities
+----------------
+
+A configuration utility needs know the button's driver index in order to map it to a feature on its controller. In addition to raw driver events, it also needs to promiscuously monitor the input translated to its platform controller to highlight features in the GUI as they're pressed.
+
+The final system can handle any number of these input listeners, monitoring input in the form of any number of platform controllers
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_1.dox
+
+> some class names are outdated, sorry
+
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_Scanning 1. Scanning for peripherals
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 1. Scanning for peripherals
+
+When Kodi starts up, the peripherals subsystem does a scan for peripherals. Kodi supports several busses including USB. Two new virtual busses have been added:
+- Add-on bus - joysticks are provided by peripheral library binary add-ons
+- Application bus - provides the keyboard, as keyboard input comes from the logical level of the application, not a specific keyboard
+
+This chart shows joysticks being scanned through the peripheral API. The keyboard is always assumed to be attached.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_2.dox
+
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_Receiving 2. Receiving joystick events
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 2. Receiving joystick events
+
+The peripherals subsystem asks the peripheral add-ons for events every frame. Joysticks are polled by the add-on and changes in state are sent back to the peripherals subsystem.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_3.dox
+
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_Events 3. Handling events
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 3. Handling events
+
+Joystick drivers present three kinds of elements:
+- Buttons
+- Hats
+- Axes
+
+Most of the time we want to know how these map to a particular system's controller (Kodi uses the Xbox 360 profile).
+The controller configuration GUI, however, also needs access to the raw driver elements. There is an event handler for both of these situations.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_4.dox
+
+@note CGenericJoystickInputHandling and CGenericJoystickButtonMapping are now called CInputHandling and CButtonMapping, respectively.
+
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_Input 4. Handling input for the Game API
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 4. Handling input for the Game API
+
+When a port is opened by the Game API, it is assigned an input handler that receives driver events involving driver
+elements, and dispatches events in the form of the desired controller.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_5.dox
+
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_DriverElements 5. Mapping driver elements to the system's controller
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 5. Mapping driver elements to the system's controller
+
+This input handler uses an internal button map to translate driver elements to the desired system controller.
+Currently, all button mapping and translating is done inside peripheral add-ons.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_6.dox
+
+A sample **buttonmap.xml** from the add-on's userdata folder `userdata/addon_data/peripheral.joystick`:
+
+~~~~~~~~~~~~~~~~xml
+<?xml version="1.0" ?>
+<buttonmap>
+ <devices>
+ <device name="Keyboard" provider="application">
+ <controller id="game.controller.default">
+ <feature name="x" button="128" />
+ </controller>
+ <controller id="game.controller.nes">
+ <feature name="a" button="90" />
+ <feature name="b" button="88" />
+ <feature name="down" button="129" />
+ <feature name="left" button="130" />
+ <feature name="right" button="131" />
+ <feature name="select" button="92" />
+ <feature name="start" button="13" />
+ <feature name="up" button="128" />
+ </controller>
+ </device>
+ <device name="Gamepad F310" provider="cocoa" vid="1133" pid="1133">
+ <controller id="game.controller.default">
+ <feature name="a" button="0" />
+ <feature name="b" button="1" />
+ <feature name="x" button="2" />
+ <feature name="y" button="3" />
+ <feature name="lefttrigger" axis="-4" />
+ <feature name="righttrigger" axis="-5" />
+ </controller>
+ </device>
+ </devices>
+</buttonmap>
+~~~~~~~~~~~~~~~~
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_Translating 6. Translating Kodi controller to libretro's "RetroPad"
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 6. Translating Kodi controller to libretro's "RetroPad"
+
+Unfortunately, libretro uses a fixed controller (called the RetroPad) for all of its cores, instead of a
+separate controller per system like Kodi. Therefore, each core needs a map of how its Kodi controller
+translates to the RetroPad.
+
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_7.dox
+
+~~~~~~~~~~~~~~~~xml
+<?xml version="1.0" encoding="UTF-8"?>
+<buttonmap>
+ <controller id="game.controller.nes" type="joypad">
+ <feature name="a" mapto="a"/>
+ <feature name="b" mapto="b"/>
+ <feature name="start" mapto="start"/>
+ <feature name="select" mapto="select"/>
+ <feature name="up" mapto="up"/>
+ <feature name="down" mapto="down"/>
+ <feature name="right" mapto="right"/>
+ <feature name="left" mapto="left"/>
+ </controller>
+ <controller id="game.controller.nes.zapper" type="lightgun">
+ <feature name="trigger" mapto="trigger"/>
+ </controller>
+</buttonmap>
+~~~~~~~~~~~~~~~~
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_KodiInput 7. Kodi Input
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 7. Kodi Input
+
+If the event isn't handled by the Game API, it is sent to a default controller (basically a Xbox 360 controller).
+The default controller translates it to a key for the file joystick.xml.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_8.dox
+
+joystick.xml belongs to Kodi's [keymap system](http://kodi.wiki/view/Keymap). It maps a standardized Xbox
+360 controller to Kodi actions. It looks something like this:
+~~~~~~~~~~~~~~~~xml
+<?xml version="1.0" encoding="UTF-8"?>
+<keymap>
+ <global>
+ <joystick>
+ <a>Select</a>
+ <b>Back</b>
+ <x>ContextMenu</x>
+ <y>FullScreen</y>
+ <start>ActivateWindow(PlayerControls)</start>
+ <back>Back</back>
+ <left>Left</left>
+ <right>Right</right>
+ <up>Up</up>
+ <down>Down</down>
+ <leftthumbbutton>Screenshot</leftthumbbutton>
+ <rightthumbbutton>ActivateWindow(ShutdownMenu)</rightthumbbutton>
+ <leftstickleft>AnalogSeekBack</leftstickleft>
+ <leftstickright>AnalogSeekForward</leftstickright>
+ <rightstickup>VolumeUp</rightstickup>
+ <rightstickdown>VolumeDown</rightstickdown>
+ <guide>ActivateWindow(Home)</guide>
+ <lefttrigger>ScrollUp</lefttrigger>
+ <righttrigger>ScrollDown</righttrigger>
+ </joystick>
+ </global>
+</keymap>
+~~~~~~~~~~~~~~~~
+
+Previously, this was 4,000 lines of XML across many files that encoded a large database of how the
+buttons/hats/axes reported by the driver map to Kodi actions depending on driver name and platform.
+This mass of data has been moved to a peripheral add-on; joystick keymapping is now a much more
+pleasant experience.
+
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_ButtonMapping 8. Button mapping (controller configuration)
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 8. Button mapping (controller configuration)
+
+When the controller's button dialog wants the user to press a button, it creates a button mapper for the controller it belongs to.
+
+<img src="modules_cpp_peripheral_Docs_Lifetime_9.png" width="100%">
+
+It then waits for an event. When the event arrives, the dialog tells its button mapper to map the event to the controller feature being mapped.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_9.dox
+
+*/
+
+/*!
+@defgroup cpp_kodi_addon_peripheral_Docs_Lifetime_KeyboardInput 9. Keyboard input
+@ingroup cpp_kodi_addon_peripheral_Docs_Lifetime
+
+# 9. Keyboard input
+
+Keyboard input is really quite simple. It just emulates a joystick with a large number of buttons.
+Any event handler down the chain that can handle joystick input can request to monitor the keyboard
+as a raw device or as any available controller profile.
+
+NES emulators, for example, don't know if their NES controller is being emulated by a joystick or a keyboard. The event handlers are identical for both.
+
+When the controller's button dialog wants the user to press a button, it creates a button mapper for the controller it belongs to.
+
+@include{doc} Modules/modules_cpp_peripheral_lifetime_diagram_10.dox
+
+*/
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_ControllerInput_1.jpg b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_ControllerInput_1.jpg
new file mode 100644
index 0000000..655b442
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_ControllerInput_1.jpg
Binary files differ
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_Lifetime_9.png b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_Lifetime_9.png
new file mode 100644
index 0000000..44a1de2
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_Docs_Lifetime_9.png
Binary files differ
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_1.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_1.dox
new file mode 100644
index 0000000..43849f0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_1.dox
@@ -0,0 +1,294 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _1 [
+ label = <<b>Joystick</b>>
+ ];
+ _2 [
+ label = <<b>Joystick<br/>Event</b>>
+ ];
+ _3 [
+ label = <<b>Keyboard</b>>
+ ];
+ _4 [
+ label = <<b>Keyboard<br/>Event</b>>
+ ];
+
+ _5 [
+ label = <<b>Joystick</b><br/><font color="#777777"><i>CJoystick</i></font>>;
+ ]
+ _6 [
+ label = <<b>Peripheral Event</b><br/><font color="#777777"><i>kodi::addon::PeripheralEvent</i></font>>;
+ ]
+ _7 [
+ label = <<b>ButtonMap</b><br/><font color="#777777"><i>kodi::addon::JoystickFeatures*</i></font>>;
+ ]
+
+ _8 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>JOYSTICK_INFO</i></font>>;
+ ]
+ _9 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>PERIPHERAL_EVENT</i></font>>;
+ ]
+ _10 [
+ label = <<b>C structs</b><br/><font color="#777777"><i>JOYSTICK_FEATURE*</i></font>>;
+ ]
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _19 [
+ label = <<b>Joystick Imitation</b><br/><font color="#777777"><i>CGenericKeyboadHandler</i></font>>
+ ]
+
+ _20 [
+ label = <<b>Button Map</b><br/><font color="#777777"><i>CAddonJoystickButtonMap</i></font>>
+ ]
+
+ _21 [
+ label = <<b>Game Controller</b><br/><font color="#777777"><i>CControllerInput</i></font>>
+ ]
+
+ _22 [
+ label = <<b>Game Add-on</b><br/><font color="#777777"><i>CGameClient</i></font>>
+ ]
+
+ _23 [
+ label = <<b>Button Dialog</b><br/><font color="#777777"><i>CGUIDialogControllerInput</i></font>>
+ ]
+
+ _24 [
+ label = <<b>Game Controller Add-ons</b><br/><font color="#777777"><i>CGameController</i></font>>
+ ]
+
+ _25 [
+ label = <<b>Default Controller</b><br/><font color="#777777"><i>CDefaultController</i></font>>
+ ]
+
+ _26 [
+ label = <<b>Kodi Input Handler</b><br/><font color="#777777"><i>CButtonKeyHandler</i></font>>
+ ]
+
+ _27 [
+ label = <<b>Button Mapper</b><br/><font color="#777777"><i>CButtonMapper</i></font>>
+ ]
+
+ _28 [
+ label = <<b>Libretro Device</b><br/><font color="#777777"><i>CLibretroDevice</i></font>>
+ ]
+
+ _29 [
+ label = <<b>Libretro Core</b><br/><font color="#777777"><i>CLibretroDll</i></font>>
+ ]
+
+ _1 -> _5 [penwidth=3, weight=25];
+ _2 -> _6 [penwidth=3, weight=2];
+ _3 -> _13 [penwidth=3, weight=100];
+ _4 -> _14 [penwidth=3, weight=15];
+
+ _5 -> _8 [penwidth=3, weight=50];
+ _6 -> _9 [penwidth=3, weight=50];
+ _7 -> _10 [dir=both, penwidth=3, weight=100];
+ _10 -> _20 [dir=both, penwidth=3, weight=2];
+
+ _8 -> _11 [penwidth=3];
+ _9 -> _12 [penwidth=3, weight=21];
+
+ _14 -> _19 [penwidth=3];
+ _19 -> _12 [penwidth=3];
+
+ _12 -> _15 [penwidth=3];
+ _12 -> _16 [penwidth=3];
+
+ _15 -> { _21, _25 } [penwidth=3];
+ _16 -> _23 [penwidth=3, dir=both, weight=0];
+ _23 -> _24 [penwidth=3, dir=back, weight=0];
+ _21 -> _22 [penwidth=3, weight=5];
+ _25 -> _26 [penwidth=3, weight=4];
+ _27 -> _28 -> _29 [penwidth=3, dir=forward, constraint=false, weight=0];
+ _22 -> _28 [penwidth=3, weight=0];
+ _24 -> _21 [penwidth=3, weight=0];
+ edge[constraint=false];
+ _20 -> { _15, _16 } [penwidth=3, weight=5];
+
+
+ subgraph cluster_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>OS</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _1 [style=filled, fillcolor=white];
+ _2 [style=filled, fillcolor=white];
+ _3 [style=filled, fillcolor=white];
+ _4 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_2 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Add-on</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _5 [style=filled, fillcolor=white];
+ _6 [style=filled, fillcolor=white];
+ _7 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _8 [style=filled, fillcolor=white];
+ _9 [style=filled, fillcolor=white];
+ _10 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_7_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "-" [
+ color="red"
+ fontcolor="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_7_3 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _19 [style=filled, fillcolor=white];
+ _20 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_8 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Game API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _21 [style=filled, fillcolor=white];
+ _22 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_9 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Configuration GUI</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _23 [style=filled, fillcolor=white];
+ _24 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_10 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Kodi Input</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _25 [style=filled, fillcolor=white];
+ _26 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_11 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Libretro API Wrapper</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ _27 [style=filled, fillcolor=white];
+ _28 [style=filled, fillcolor=white];
+ _29 [style=filled, fillcolor=white];
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_10.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_10.dox
new file mode 100644
index 0000000..5a1d8bf
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_10.dox
@@ -0,0 +1,149 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _1 [
+ label = <<b>Joystick</b>>
+ ];
+ _2 [
+ label = <<b>Joystick<br/>Event</b>>
+ ];
+ _3 [
+ label = <<b>Keyboard</b>>
+ ];
+ _4 [
+ label = <<b>Keyboard<br/>Event</b>>
+ ];
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _19 [
+ label = <<b>Joystick Imitation</b><br/><font color="#777777"><i>CGenericKeyboadHandler</i></font>>
+ ]
+
+ _20 [
+ label = <<b>Button Map</b><br/><font color="#777777"><i>CAddonJoystickButtonMap</i></font>>
+ ]
+
+ _4 -> _14 [penwidth=3, weight=-1];
+ _14 -> _19 [penwidth=3, weight=2];
+ _19 -> _12 [penwidth=3, weight=0];
+ _12 -> _15 [penwidth=3, weight=1];
+ _12 -> _16 [penwidth=3, weight=4];
+
+ subgraph cluster_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>OS</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _1 [style=filled, fillcolor=white];
+ _2 [style=filled, fillcolor=white];
+ _3 [style=filled, fillcolor=white];
+ _4 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_7_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "-" [
+ color="red"
+ fontcolor="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_7_3 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _19 [style=filled, fillcolor=white];
+ _20 [style=filled, fillcolor=white];
+ }
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_2.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_2.dox
new file mode 100644
index 0000000..96a6474
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_2.dox
@@ -0,0 +1,139 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _1 [
+ label = <<b>Joystick</b>>
+ ];
+ _2 [
+ label = <<b>Joystick<br/>Event</b>>
+ ];
+ _3 [
+ label = <<b>Keyboard</b>>
+ ];
+ _4 [
+ label = <<b>Keyboard<br/>Event</b>>
+ ];
+
+ _5 [
+ label = <<b>Joystick</b><br/><font color="#777777"><i>CJoystick</i></font>>;
+ ]
+ _6 [
+ label = <<b>Peripheral Event</b><br/><font color="#777777"><i>kodi::addon::PeripheralEvent</i></font>>;
+ ]
+ _7 [
+ label = <<b>ButtonMap</b><br/><font color="#777777"><i>kodi::addon::JoystickFeatures*</i></font>>;
+ ]
+
+ _8 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>JOYSTICK_INFO</i></font>>;
+ ]
+ _9 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>PERIPHERAL_EVENT</i></font>>;
+ ]
+ _10 [
+ label = <<b>C structs</b><br/><font color="#777777"><i>JOYSTICK_FEATURE*</i></font>>;
+ ]
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _1 -> _5 [penwidth=3, weight=5];
+ _3 -> _13 [penwidth=3, weight=0];
+ _5 -> _8 [penwidth=3, weight=10];
+ _8 -> _11 [penwidth=3, weight=5];
+
+ subgraph cluster_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>OS</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _1 [style=filled, fillcolor=white];
+ _2 [style=filled, fillcolor=white];
+ _3 [style=filled, fillcolor=white];
+ _4 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_2 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Add-on</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _5 [style=filled, fillcolor=white];
+ _6 [style=filled, fillcolor=white];
+ _7 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _8 [style=filled, fillcolor=white];
+ _9 [style=filled, fillcolor=white];
+ _10 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_3.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_3.dox
new file mode 100644
index 0000000..e539828
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_3.dox
@@ -0,0 +1,138 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _1 [
+ label = <<b>Joystick</b>>
+ ];
+ _2 [
+ label = <<b>Joystick<br/>Event</b>>
+ ];
+ _3 [
+ label = <<b>Keyboard</b>>
+ ];
+ _4 [
+ label = <<b>Keyboard<br/>Event</b>>
+ ];
+
+ _5 [
+ label = <<b>Joystick</b><br/><font color="#777777"><i>CJoystick</i></font>>;
+ ]
+ _6 [
+ label = <<b>Peripheral Event</b><br/><font color="#777777"><i>kodi::addon::PeripheralEvent</i></font>>;
+ ]
+ _7 [
+ label = <<b>ButtonMap</b><br/><font color="#777777"><i>kodi::addon::JoystickFeatures*</i></font>>;
+ ]
+
+ _8 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>JOYSTICK_INFO</i></font>>;
+ ]
+ _9 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>PERIPHERAL_EVENT</i></font>>;
+ ]
+ _10 [
+ label = <<b>C structs</b><br/><font color="#777777"><i>JOYSTICK_FEATURE*</i></font>>;
+ ]
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _2 -> _6 [penwidth=3, weight=5];
+ _6 -> _9 [penwidth=3, weight=10];
+ _9 -> _12 [penwidth=3, weight=5];
+
+ subgraph cluster_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>OS</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _1 [style=filled, fillcolor=white];
+ _2 [style=filled, fillcolor=white];
+ _3 [style=filled, fillcolor=white];
+ _4 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_2 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Add-on</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _5 [style=filled, fillcolor=white];
+ _6 [style=filled, fillcolor=white];
+ _7 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _8 [style=filled, fillcolor=white];
+ _9 [style=filled, fillcolor=white];
+ _10 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_4.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_4.dox
new file mode 100644
index 0000000..b21caf3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_4.dox
@@ -0,0 +1,94 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _12 -> _15 [penwidth=3, weight=-10];
+ _12 -> _16 [penwidth=3];
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_5.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_5.dox
new file mode 100644
index 0000000..cc9a0dd
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_5.dox
@@ -0,0 +1,113 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _21 [
+ label = <<b>Game Controller</b><br/><font color="#777777"><i>CControllerInput</i></font>>
+ ]
+
+ _22 [
+ label = <<b>Game Add-on</b><br/><font color="#777777"><i>CGameClient</i></font>>
+ ]
+
+ _12 -> _15 [penwidth=3, weight=10];
+ _15 -> _21 [penwidth=3, weight=10];
+ _21 -> _22 [penwidth=3, weight=0];
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_8 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Game API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _21 [style=filled, fillcolor=white];
+ _22 [style=filled, fillcolor=white];
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_6.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_6.dox
new file mode 100644
index 0000000..f48a12b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_6.dox
@@ -0,0 +1,185 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _5 [
+ label = <<b>Joystick</b><br/><font color="#777777"><i>CJoystick</i></font>>;
+ ]
+ _6 [
+ label = <<b>Peripheral Event</b><br/><font color="#777777"><i>kodi::addon::PeripheralEvent</i></font>>;
+ ]
+ _7 [
+ label = <<b>ButtonMap</b><br/><font color="#777777"><i>kodi::addon::JoystickFeatures*</i></font>>;
+ ]
+
+ _8 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>JOYSTICK_INFO</i></font>>;
+ ]
+ _9 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>PERIPHERAL_EVENT</i></font>>;
+ ]
+ _10 [
+ label = <<b>C structs</b><br/><font color="#777777"><i>JOYSTICK_FEATURE*</i></font>>;
+ ]
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _19 [
+ label = <<b>Joystick Imitation</b><br/><font color="#777777"><i>CGenericKeyboadHandler</i></font>>
+ ]
+
+ _20 [
+ label = <<b>Button Map</b><br/><font color="#777777"><i>CAddonJoystickButtonMap</i></font>>
+ ]
+
+ _21 [
+ label = <<b>Game Controller</b><br/><font color="#777777"><i>CControllerInput</i></font>>
+ ]
+
+ _22 [
+ label = <<b>Game Add-on</b><br/><font color="#777777"><i>CGameClient</i></font>>
+ ]
+
+ _7 -> _10 [penwidth=3];
+ _10 -> _20 [penwidth=3];
+ _20 -> _15 [penwidth=3];
+ _12 -> _15 [penwidth=3];
+ _15 -> _21 [penwidth=3];
+ _21 -> _22 [penwidth=3];
+
+ subgraph cluster_2 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Add-on</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _5 [style=filled, fillcolor=white];
+ _6 [style=filled, fillcolor=white];
+ _7 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _8 [style=filled, fillcolor=white];
+ _9 [style=filled, fillcolor=white];
+ _10 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_7_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "-" [
+ color="red"
+ fontcolor="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_7_3 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _19 [style=filled, fillcolor=white];
+ _20 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_8 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Game API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _21 [style=filled, fillcolor=white];
+ _22 [style=filled, fillcolor=white];
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_7.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_7.dox
new file mode 100644
index 0000000..9393398
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_7.dox
@@ -0,0 +1,130 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _19 [
+ label = <<b>Joystick Imitation</b><br/><font color="#777777"><i>CGenericKeyboadHandler</i></font>>
+ ]
+
+ _20 [
+ label = <<b>Button Map</b><br/><font color="#777777"><i>CAddonJoystickButtonMap</i></font>>
+ ]
+
+ _21 [
+ label = <<b>Game Controller</b><br/><font color="#777777"><i>CControllerInput</i></font>>
+ ]
+
+ _22 [
+ label = <<b>Game Add-on</b><br/><font color="#777777"><i>CGameClient</i></font>>
+ ]
+
+ _23 [
+ label = <<b>Button Dialog</b><br/><font color="#777777"><i>CGUIDialogControllerInput</i></font>>
+ ]
+
+ _24 [
+ label = <<b>Game Controller Add-ons</b><br/><font color="#777777"><i>CGameController</i></font>>
+ ]
+
+ _27 [
+ label = <<b>Button Mapper</b><br/><font color="#777777"><i>CButtonMapper</i></font>>
+ ]
+
+ _28 [
+ label = <<b>Libretro Device</b><br/><font color="#777777"><i>CLibretroDevice</i></font>>
+ ]
+
+ _29 [
+ label = <<b>Libretro Core</b><br/><font color="#777777"><i>CLibretroDll</i></font>>
+ ]
+
+ _15 -> _21 [penwidth=3, weight=10];
+ _21 -> _22 [penwidth=3, weight=5];
+ _27 -> _28 -> _29 [penwidth=3, dir=forward, constraint=false, weight=10];
+ _22 -> _28 [penwidth=3, weight=10];
+ _24 -> _21 [penwidth=3, weight=10];
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_7_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "-" [
+ color="red"
+ fontcolor="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_7_3 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _19 [style=filled, fillcolor=white];
+ _20 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_8 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Game API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _21 [style=filled, fillcolor=white];
+ _22 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_9 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Configuration GUI</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _23 [style=filled, fillcolor=white];
+ _24 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_11 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Libretro API Wrapper</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ _27 [style=filled, fillcolor=white];
+ _28 [style=filled, fillcolor=white];
+ _29 [style=filled, fillcolor=white];
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_8.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_8.dox
new file mode 100644
index 0000000..ef50096
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_8.dox
@@ -0,0 +1,86 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _19 [
+ label = <<b>Joystick Imitation</b><br/><font color="#777777"><i>CGenericKeyboadHandler</i></font>>
+ ]
+
+ _20 [
+ label = <<b>Button Map</b><br/><font color="#777777"><i>CAddonJoystickButtonMap</i></font>>
+ ]
+
+ _25 [
+ label = <<b>Default Controller</b><br/><font color="#777777"><i>CDefaultController</i></font>>
+ ]
+
+ _26 [
+ label = <<b>Kodi Input Handler</b><br/><font color="#777777"><i>CButtonKeyHandler</i></font>>
+ ]
+
+ _15 -> _25 [penwidth=3];
+ _25 -> _26 [penwidth=3, weight=4];
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_7_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "-" [
+ color="red"
+ fontcolor="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_7_3 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _19 [style=filled, fillcolor=white];
+ _20 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_10 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Kodi Input</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _25 [style=filled, fillcolor=white];
+ _26 [style=filled, fillcolor=white];
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_9.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_9.dox
new file mode 100644
index 0000000..482e361
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp_peripheral_lifetime_diagram_9.dox
@@ -0,0 +1,215 @@
+@dot
+digraph D {
+ graph [label="Orthogonal edges", splines=ortho, nodesep=1.0];
+ node [shape=box fontname=Arial];
+
+ rankdir=LR;
+ color = "white"
+ bgcolor = "white"
+ fillcolor = "white"
+ fontcolor = "white"
+ pencolor = "white"
+
+ _1 [
+ label = <<b>Joystick</b>>
+ ];
+ _2 [
+ label = <<b>Joystick<br/>Event</b>>
+ ];
+ _3 [
+ label = <<b>Keyboard</b>>
+ ];
+ _4 [
+ label = <<b>Keyboard<br/>Event</b>>
+ ];
+
+ _5 [
+ label = <<b>Joystick</b><br/><font color="#777777"><i>CJoystick</i></font>>;
+ ]
+ _6 [
+ label = <<b>Peripheral Event</b><br/><font color="#777777"><i>kodi::addon::PeripheralEvent</i></font>>;
+ ]
+ _7 [
+ label = <<b>ButtonMap</b><br/><font color="#777777"><i>kodi::addon::JoystickFeatures*</i></font>>;
+ ]
+
+ _8 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>JOYSTICK_INFO</i></font>>;
+ ]
+ _9 [
+ label = <<b>C struct</b><br/><font color="#777777"><i>PERIPHERAL_EVENT</i></font>>;
+ ]
+ _10 [
+ label = <<b>C structs</b><br/><font color="#777777"><i>JOYSTICK_FEATURE*</i></font>>;
+ ]
+
+ _11 [
+ label = <<b>Joystick Peripheral</b><br/><font color="#777777"><i>CPeripheralJoystick</i></font>>
+ ]
+
+ _12 [
+ label = <<b>Event Handling</b><br/><font color="#777777"><i>IJoystickDriverHandler</i></font>>
+ ]
+
+ _13 [
+ label = <<b>Keyboard Peripheral</b><br/><font color="#777777"><i>CPeripheralKeyboard</i></font>>
+ ]
+
+ _14 [
+ label = <<b>Keyboard Handling</b><br/><font color="#777777"><i>IKeyboardHandler</i></font>>
+ ]
+
+ _15 [
+ label = <<b>Input Handling</b><br/><font color="#777777"><i>CGenericJoystickInputHandling</i></font>>
+ ]
+
+ _16 [
+ label = <<b>Button Mapping</b><br/><font color="#777777"><i>CGenericJoystickButtonMapping</i></font>>
+ ]
+
+ _19 [
+ label = <<b>Joystick Imitation</b><br/><font color="#777777"><i>CGenericKeyboadHandler</i></font>>
+ ]
+
+ _20 [
+ label = <<b>Button Map</b><br/><font color="#777777"><i>CAddonJoystickButtonMap</i></font>>
+ ]
+
+ _23 [
+ label = <<b>Button Dialog</b><br/><font color="#777777"><i>CGUIDialogControllerInput</i></font>>
+ ]
+
+ _24 [
+ label = <<b>Game Controller Add-ons</b><br/><font color="#777777"><i>CGameController</i></font>>
+ ]
+
+ _2 -> _6 [penwidth=3, weight=2];
+ _6 -> _9 [penwidth=3, weight=10];
+ _7 -> _10 [dir=back, penwidth=3, weight=0];
+ _10 -> _20 [dir=back, penwidth=3, weight=-2];
+ _9 -> _12 [penwidth=3, weight=21];
+ _12 -> _16 [penwidth=3];
+ _16 -> _23 [penwidth=3, dir=both, weight=20];
+ _23 -> _24 [penwidth=3, dir=back, weight=0];
+ edge[constraint=false];
+ _20 -> _16 [dir=back, penwidth=3, weight=0];
+
+
+ subgraph cluster_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>OS</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _1 [style=filled, fillcolor=white];
+ _2 [style=filled, fillcolor=white];
+ _3 [style=filled, fillcolor=white];
+ _4 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_2 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Add-on</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _5 [style=filled, fillcolor=white];
+ _6 [style=filled, fillcolor=white];
+ _7 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral API</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _8 [style=filled, fillcolor=white];
+ _9 [style=filled, fillcolor=white];
+ _10 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_4 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Peripheral Busses</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ subgraph cluster_4_1 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Add-on Bus</b></font><br/><font color="#777777"><i>CPeripheralBusAddon</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _11 [style=filled, fillcolor=white];
+ _12 [style=filled, fillcolor=white];
+
+ }
+
+ subgraph cluster_4_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "" [
+ color="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_4_3 {
+ graph [nodesep=6, ranksep=4];
+ label = <<font point-size='18'><b>Virtual Application Bus</b></font><br/><font color="#777777"><i>CPeripheralBusApplication</i></font>>;
+ fontcolor = "black";
+ bgcolor = "white";
+
+ _13 [style=filled, fillcolor=white];
+ _14 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_7 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Input Library</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+ rank=same;
+
+ subgraph cluster_7_1 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _15 [style=filled, fillcolor=white];
+ _16 [style=filled, fillcolor=white];
+ }
+
+ subgraph cluster_7_2 {
+ graph [nodesep=6, ranksep=4];
+ label = "";
+ "-" [
+ color="red"
+ fontcolor="red"
+ bgcolor = "red";
+ ];
+ pencolor = "red";
+ }
+
+ subgraph cluster_7_3 {
+ graph [nodesep=6, ranksep=4];
+ label = ""
+ pencolor = "red";
+ _19 [style=filled, fillcolor=white];
+ _20 [style=filled, fillcolor=white];
+ }
+ }
+
+ subgraph cluster_9 {
+ graph [nodesep=6, ranksep=4];
+ label = <<b><font point-size='20'>Configuration GUI</font></b>>;
+ fontcolor = "white";
+ bgcolor = "red";
+
+ _23 [style=filled, fillcolor=white];
+ _24 [style=filled, fillcolor=white];
+ }
+}
+@enddot
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_general.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_general.dox
new file mode 100644
index 0000000..f7e04ca
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_general.dox
@@ -0,0 +1,8 @@
+/*!
+
+\page general_parts General Development parts
+\brief \doc_header{ General Add-On Development parts }
+
+\subpage modules__infolabels_boolean_conditions
+\subpage page_List_of_built_in_functions
+*/
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_python.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_python.dox
new file mode 100644
index 0000000..98783b8
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_python.dox
@@ -0,0 +1,299 @@
+/*!
+
+
+\defgroup python Python
+\image html logo-python.png
+\brief \htmlonly
+ <h3><span style="text-decoration: underline;"><span style="font-style: italic;"><span
+ style="color: rgb(102, 102, 102);">Python Add-On Development</span></span></span></h3>
+ \endhtmlonly
+
+Kodi includes a built-in [Python interpreter](http://en.wikipedia.org/wiki/Python_%28programming_language%29)
+that allows users to develop add-ons (scripts and plugins) that interface easily
+and cleanly with the Kodi dashboard. These add-ons can extend the functionality
+of Kodi without requiring extensive programming experience or ability. While you
+may not feel comfortable browsing the Kodi source code and submitting patches (or
+even bug reports), you can learn how to write a script or plugin with just a few
+hours' practice, using the information available in these pages.
+
+This page is intended as an introduction to Kodi Python for new developers, and
+a quick reference for more experienced programmers. If you're not interested in
+programming, you might want to visit [this page](http://kodi.wiki/view/Add-ons)
+for information about installing and using Python add-ons as an end user. If
+you're already familiar with Kodi Python, you can probably skip on down to the
+[environment details](http://kodi.wiki/view/Python_Development#Environment_details)
+or the [resource links](http://kodi.wiki/view/Python_Development#Resource_links)
+below for quick reference material.
+
+_ _ _
+
+Built-in modules
+----------------
+
+In addition to the standard libraries, Kodi [Python](https://www.python.org/)
+uses a handful of custom modules to expose Kodi functionality to Python.
+
+| Module | Description |
+|------------------------------------:|:-----------------------------------------------------------|
+| \ref python_xbmc "xbmc" | Offers classes and functions that provide information about the media currently playing and that allow manipulation of the media player (such as starting a new song). You can also find system information using the functions available in this library.
+| \ref python_xbmcgui "xbmcgui" | Offers classes and functions that manipulate the Graphical User Interface through windows, dialogs, and various control widgets.
+| \ref python_xbmcplugin "xbmcplugin" | Offers classes and functions that allow a developer to present information through Kodi's standard menu structure. While plugins don't have the same flexibility as scripts, they boast significantly quicker development time and a more consistent user experience.
+| \ref python_xbmcaddon "xbmcaddon" | Offers classes and functions that manipulate the add-on settings, information and localization.
+| \ref python_xbmcvfs "xbmcvfs" | Offers classes and functions that allow access to the Virtual File Server (VFS) which you can use to manipulate files and folders.
+| \ref python_xbmcwsgi "xbmcwsgi" | The [<b>Web Server Gateway Interface (WSGI)</b>](https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface) is a specification for simple and universal interface between web servers and web applications or frameworks for the Python programming language.
+| \ref python_xbmcdrm "xbmcdrm" | Offers classes and functions to create and manipulate a DRM CryptoSession .
+
+_ _ _
+
+Installing additional modules
+----------------
+
+Additional modules may be installed by simply adding the module to the root
+folder of your add-on.
+
+A common way to organized third-party modules that are not part of add-on source
+code itself, is to add a lib directory and place an __init__.py file and other
+third-party modules inside it. These modules may then normally be imported using
+from lib import some module.
+
+_ _ _
+
+Python plugins versus scripts
+----------------
+
+Please do not confuse "Plugins" with "Scripts". Unlike the Scripts, Plugins are
+not meant to be directly invoked by the user. Instead, Plugins are automatically
+invoked when the user enters such a virtual folder. Do not try to run Plugins
+files from the scripts window as that will only give you a weird error message.
+Plugins, unlike Scripts, do not really provide new functionality to Kodi,
+instead what they do do is provide an easy way to present content listings in
+Kodi through the native GUI interface.
+
+_ _ _
+
+Script development
+----------------
+
+If you're new to Python programming (or just new to Kodi Python), the easiest
+way to get started is with a script. The traditional Hello World program,
+written as an Kodi Python script, would look like this:
+~~~~~~~~~~~~~{.py}
+print("Hello World!")
+~~~~~~~~~~~~~
+That's the same code you would enter at the Python command line, because Kodi
+runs a full-featured, standard Python interpreter (for more information
+concerning the current version number and included modules see the environment
+details below). If you're already familiar with Python programming, the only new
+challenge is learning the custom modules that allow you to gather information
+from Kodi and manipulate the Graphical User Interface (GUI).
+
+There are some excellent tutorials available to introduce you to Kodi scripting
+(and Python in general). See the [HOW-TO](http://kodi.wiki/view/HOW-TO_write_Python_Scripts)
+included in the Kodi Online Manual, or visit Alexpoet's Kodi Scripting site for
+a popular beginner's tutorial (PDF).
+
+_ _ _
+Plugin development
+----------------
+
+While scripts offer you flexibility and full control over the Kodi GUI, plugins
+allow you to quickly and consistently present information to the user through
+the standard Kodi menu structure.
+
+When a user launches a plugin, the plugin generates a list of menu items and
+hands them to Kodi to draw on the screen (regardless of screen resolution, skin,
+or any other user setting). While plugin developers lose some amount of control
+over the presentation, they no longer have to make up their own UIs, or worry
+about creating a usable look and feel across multiple displays.
+
+Plugins are most commonly used to scrape websites for links to streaming videos,
+displaying the video list in Kodi just like it would movie files on the local
+hard drive, but a plugin can be used anywhere a script could, as long as the
+menu structure is a sufficient GUI for the add-on's needs.
+
+Also, note that a script can launch a plugin, and a plugin can launch a script
+(and, for that matter, it can call all the same functions available to a script)
+so the distinction is more theoretical than practical.
+
+
+@{
+\ingroup python
+\defgroup python_xbmc Library - xbmc
+
+\ingroup python
+\defgroup python_xbmcgui Library - xbmcgui
+
+\ingroup python
+\defgroup python_xbmcplugin Library - xbmcplugin
+
+\ingroup python
+\defgroup python_xbmcaddon Library - xbmcaddon
+
+\ingroup python
+\defgroup python_xbmcvfs Library - xbmcvfs
+
+\ingroup python
+\defgroup python_xbmcwsgi Library - xbmcwsgi
+@brief **Web Server Gateway Interface**
+
+The [<b>Web Server Gateway Interface (WSGI)</b>](https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface)
+is a specification for simple and universal interface between web servers and
+web applications or frameworks for the Python programming language.
+
+\ingroup python
+\defgroup python_xbmcdrm Library - xbmcdrm
+@}
+
+*/
+
+/*!
+@page python_v20 Python API v20
+\python_removed_function{
+ translatePath,
+ "",
+ <b>xbmc.translatePath()</b> function was removed completely. Use <b>xbmcvfs.translatePath()</b>.
+}
+@page python_v19 Python API v19
+\python_removed_function{
+ onDatabaseUpdated,
+ "",
+ <b>xbmc.monitor().onDatabaseUpdated()</b> function was removed completely.
+}
+\python_removed_function{
+ onDatabaseScanStarted,
+ "",
+ <b>xbmc.monitor().onDatabaseScanStarted()</b> function was removed completely.
+}
+\python_removed_function{
+ onAbortRequested,
+ "",
+ <b>xbmc.monitor().onAbortRequested()</b> function was removed completely.
+}
+\python_removed_function{
+ create,
+ "",
+ <b>xbmcgui.DialogBusy().create()</b> function was removed completely.
+}
+\python_removed_function{
+ update,
+ "",
+ <b>xbmcgui.DialogBusy().update()</b> function was removed completely.
+}
+\python_removed_function{
+ close,
+ "",
+ <b>xbmcgui.DialogBusy().close()</b> function was removed completely.
+}
+\python_removed_function{
+ iscanceled,
+ "",
+ <b>xbmcgui.DialogBusy().iscanceled()</b> function was removed completely.
+}
+\python_removed_function{
+ setIconImage,
+ "",
+ <b>xbmcgui.ListItem().setIconImage()</b> function was removed completely.
+}
+\python_removed_function{
+ setThumbnailImage,
+ "",
+ <b>xbmcgui.ListItem().setThumbnailImage()</b> function was removed completely.
+}
+\python_removed_function{
+ getdescription,
+ "",
+ <b>xbmcgui.ListItem().getdescription()</b> function was removed completely.
+}
+\python_removed_function{
+ getduration,
+ "",
+ <b>xbmcgui.ListItem().getduration()</b> function was removed completely.
+}
+\python_removed_function{
+ getfilename,
+ "",
+ <b>xbmcgui.ListItem().getfilename()</b> function was removed completely.
+}
+\python_removed_function{
+ getfilename,
+ "",
+ <b>xbmcgui.Window().getResolution()</b> function was removed completely.
+}
+\python_removed_function{
+ setCoordinateResolution,
+ "",
+ <b>xbmcgui.Window().setCoordinateResolution()</b> function was removed completely.
+}
+\python_removed_function{
+ makeLegalFilename,
+ "",
+ <b>xbmc.makeLegalFilename()</b> function was moved to the xbmcvfs module.
+}
+\python_removed_function{
+ validatePath,
+ "",
+ <b>xbmc.validatePath()</b> function was moved to the xbmcvfs module.
+}
+\python_removed_function{
+ abortRequested,
+ "",
+ <b>xbmc.abortRequested</b> flag was removed completely. Use xbmc.Monitor().abortRequested().
+}
+*/
+/*!
+@page python_v18 Python API v18
+*/
+/*!
+@page python_v17 Python API v17
+\python_removed_function{
+ getCaptureState,
+ http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmc.html#RenderCapture-getCaptureState,
+ <b>xbmc.RenderCapture().getCaptureState()</b> function was removed completely.
+}
+\python_removed_function{
+ waitForCaptureStateChangeEvent,
+ http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmc.html#RenderCapture-waitForCaptureStateChangeEvent,
+ <b>xbmc.RenderCapture().waitForCaptureStateChangeEvent()</b> function was removed completely.
+}
+\python_removed_function{
+ disableSubtitles,
+ http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmc.html#Player,
+ <b>xbmc.Player().disableSubtitles()</b> function was removed completely.
+ Use \endhtmlonly \link XBMCAddon::xbmc::Player::showSubtitles() xbmc.Player().showSubtitles(...) \endlink \htmlonly instead.
+}
+*/
+/*!
+@page python_v16 Python API v16
+*/
+/*!
+@page python_v15 Python API v15
+*/
+/*!
+@page python_v14 Python API v14
+*/
+/*!
+@page python_v13 Python API v13
+*/
+/*!
+@page python_v12 Python API v12
+\python_removed_function{
+ executehttpapi,
+ http://mirrors.kodi.tv/docs/python-docs/12.2-frodo/xbmc.html#-executehttpapi,
+ <b>xbmc.executehttpapi()</b> function was removed completely.
+}
+*/
+/*!
+@page python_revisions Python API Changes
+@brief Overview of changes on Python API for Kodi
+
+- @subpage python_v20
+- @subpage python_v19
+- @subpage python_v18
+- @subpage python_v17
+- @subpage python_v16
+- @subpage python_v15
+- @subpage python_v14
+- @subpage python_v13
+- @subpage python_v12
+
+*/
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Skin/skin.dox b/xbmc/addons/kodi-dev-kit/doxygen/Skin/skin.dox
new file mode 100644
index 0000000..e4e4fc0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Skin/skin.dox
@@ -0,0 +1,69 @@
+/*!
+
+\page skin_parts Skin Development
+@brief \doc_header{ Skin Add-On Development }
+
+Kodi includes a GUI library that allows you to skin/change everything you see.
+The images, sizes and positions of controls, colours, fonts, text, through to
+altering navigation and even adding new functionality.
+
+The skin system is quite complex. This portion of the manual is dedicated to
+providing in depth information on how it all works. It contains tips to make the
+experience a little more pleasant.
+
+If you are just getting started with skinning Kodi, then it is suggested that the
+best way to learn is by modifying one of the many existing skins that are
+available. The default skin, Estuary, includes almost all the various tricks
+and features that make the Kodi skinning engine so powerful, so is an ideal place
+to start. You may wish to start by having a look through the tutorial section on
+skinning Kodi as well as the "Skinning Kodi" article, and try modifying a window
+or two by adding a button, or altering the textures or layout.
+
+- \subpage skin_controls - Controls are the substance of your skin.
+- \subpage window_ids - List of available window names, definitions, IDs and the matching XML-file
+- \subpage Skin_Timers - Programatic time-based objects for Skins
+
+*/
+
+/*!
+@page skinning_v20 Skinning engine v20
+*/
+/*!
+@page skinning_v19 Skinning engine v19
+*/
+/*!
+@page skinning_v18 Skinning engine v18
+*/
+/*!
+@page skinning_v17 Skinning engine v17
+*/
+/*!
+@page skinning_v16 Skinning engine v16
+*/
+/*!
+@page skinning_v15 Skinning engine v15
+*/
+/*!
+@page skinning_v14 Skinning engine v14
+*/
+/*!
+@page skinning_v13 Skinning engine v13
+*/
+/*!
+@page skinning_v12 Skinning engine v12
+*/
+
+/*!
+@page skinning_revisions Skinning engine changes
+@brief Overview of changes on Skinning engine for Kodi
+
+- @subpage skinning_v20
+- @subpage skinning_v19
+- @subpage skinning_v18
+- @subpage skinning_v17
+- @subpage skinning_v16
+- @subpage skinning_v15
+- @subpage skinning_v14
+- @subpage skinning_v13
+- @subpage skinning_v12
+*/
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/kodi-dev.png b/xbmc/addons/kodi-dev-kit/doxygen/kodi-dev.png
new file mode 100644
index 0000000..315a13b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/kodi-dev.png
Binary files differ
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/main.txt b/xbmc/addons/kodi-dev-kit/doxygen/main.txt
new file mode 100644
index 0000000..8a60960
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/doxygen/main.txt
@@ -0,0 +1,49 @@
+/*!
+
+@mainpage
+
+### Welcome to the Documentation of Kodi for Add-On Development.
+
+__Kodi®__ media center, formerly known as XBMC Media Center, is a free and
+open-source media player software developed by the XBMC Foundation, a non-profit
+technology consortium. Kodi is available for multiple operating systems and
+hardware platforms, with a software 10-foot user interface for use with
+televisions and remote controls. It allows users to play and view most videos,
+music, such as audio and video podcasts from the internet, and all common
+digital media files from local and network storage media.
+
+Add-ons are extensions that can be run from inside the Kodi GUI and in
+addition to binary add-ons for the use of different systems. They are usual
+written by third party developers and published to our official repository.
+Add-ons can also be published in other repositories or as stand alone zip
+files anywhere on the internet. Examples of Add-ons include video website
+streams, scrapers, skins and scripts.
+
+#### Supported systems
+
+Currently support Kodi Add-Ons based upon Python and C++.
+
+#### Tutorials and Examples
+
+In the distribution of the library you find the two directories *tutorials*
+and *examples*. They contain subdirectories for the packages...
+The demos use third party libraries for the graphical user interface. The
+examples don't have this dependency and most examples are referred to in the
+user manual.
+
+#### License
+
+Kodi is distributed under a [GNU General Public License version 2](./LICENSE.md).
+
+\htmlonly
+<div style="display:none">
+\endhtmlonly
+
+\subpage general
+\subpage general_parts
+
+\htmlonly
+</div>
+\endhtmlonly
+
+*/
diff --git a/xbmc/addons/kodi-dev-kit/include/NOTE b/xbmc/addons/kodi-dev-kit/include/NOTE
new file mode 100644
index 0000000..ddc579c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/NOTE
@@ -0,0 +1,9 @@
+NOTE:
+
+This directory contains independent Headers to build Add-on's
+without the whole Kodi source tree. The Add-on itself can add
+this headers to his source tree without dependencies to any
+Kodi related classes or functions.
+
+Also this headers are never changed without a API Version
+change.
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h b/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
new file mode 100644
index 0000000..a626122
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
@@ -0,0 +1,1877 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "c-api/addon_base.h"
+#include "versions.h"
+
+#include <assert.h> /* assert */
+#include <stdarg.h> /* va_list, va_start, va_arg, va_end */
+
+#ifdef __cplusplus
+
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include "tools/StringUtils.h"
+
+namespace kodi
+{
+
+namespace gui
+{
+struct IRenderHelper;
+} /* namespace gui */
+
+//==============================================================================
+/// @ingroup cpp_kodi_Defs
+/// @defgroup cpp_kodi_Defs_HardwareContext using HardwareContext
+/// @brief **Hardware specific device context**\n
+/// This defines an independent value which is used for hardware and OS specific
+/// values.
+///
+/// This is basically a simple pointer which has to be changed to the desired
+/// format at the corresponding places using <b>`static_cast<...>(...)`</b>.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <d3d11_1.h>
+/// ..
+/// // Note: Device() there is used inside addon child class about
+/// // kodi::addon::CInstanceVisualization
+/// ID3D11DeviceContext1* context = static_cast<ID3D11DeviceContext1*>(kodi::addon::CInstanceVisualization::Device());
+/// ..
+/// ~~~~~~~~~~~~~
+///
+///@{
+using HardwareContext = ADDON_HARDWARE_CONTEXT;
+///@}
+//------------------------------------------------------------------------------
+
+namespace addon
+{
+
+/*!
+ * @brief Internal used structure to have stored C API data above and
+ * available for everything below.
+ */
+struct ATTR_DLL_LOCAL CPrivateBase
+{
+ // Interface function table to hold addresses on add-on and from kodi
+ static AddonGlobalInterface* m_interface;
+};
+
+/*
+ * Internally used helper class to manage processing of a "C" structure in "CPP"
+ * class.
+ *
+ * At constant, the "C" structure is copied, otherwise the given pointer is
+ * superseded and is changeable.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Example:
+ *
+ * ~~~~~~~~~~~~~{.cpp}
+ * extern "C" typedef struct C_SAMPLE_DATA
+ * {
+ * unsigned int iUniqueId;
+ * } C_SAMPLE_DATA;
+ *
+ * class CPPSampleData : public CStructHdl<CPPSampleData, C_SAMPLE_DATA>
+ * {
+ * public:
+ * CPPSampleData() = default;
+ * CPPSampleData(const CPPSampleData& sample) : CStructHdl(sample) { }
+ * CPPSampleData(const C_SAMPLE_DATA* sample) : CStructHdl(sample) { }
+ * CPPSampleData(C_SAMPLE_DATA* sample) : CStructHdl(sample) { }
+ *
+ * void SetUniqueId(unsigned int uniqueId) { m_cStructure->iUniqueId = uniqueId; }
+ * unsigned int GetUniqueId() const { return m_cStructure->iUniqueId; }
+ * };
+ *
+ * ~~~~~~~~~~~~~
+ *
+ * It also works with the following example:
+ *
+ * ~~~~~~~~~~~~~{.cpp}
+ * CPPSampleData test;
+ * // Some work
+ * C_SAMPLE_DATA* data = test;
+ * // Give "data" to Kodi
+ * ~~~~~~~~~~~~~
+ */
+template<class CPP_CLASS, typename C_STRUCT>
+class CStructHdl
+{
+public:
+ CStructHdl() : m_cStructure(new C_STRUCT()), m_owner(true) {}
+
+ CStructHdl(const CPP_CLASS& cppClass)
+ : m_cStructure(new C_STRUCT(*cppClass.m_cStructure)), m_owner(true)
+ {
+ }
+
+ CStructHdl(const C_STRUCT* cStructure) : m_cStructure(new C_STRUCT(*cStructure)), m_owner(true) {}
+
+ CStructHdl(C_STRUCT* cStructure) : m_cStructure(cStructure) { assert(cStructure); }
+
+ const CStructHdl& operator=(const CStructHdl& right)
+ {
+ assert(&right.m_cStructure);
+
+ if (this == &right)
+ return *this;
+
+ if (m_cStructure && !m_owner)
+ {
+ memcpy(m_cStructure, right.m_cStructure, sizeof(C_STRUCT));
+ }
+ else
+ {
+ if (m_owner)
+ delete m_cStructure;
+ m_owner = true;
+ m_cStructure = new C_STRUCT(*right.m_cStructure);
+ }
+ return *this;
+ }
+
+ const CStructHdl& operator=(const C_STRUCT& right)
+ {
+ assert(&right);
+
+ if (m_cStructure == &right)
+ return *this;
+
+ if (m_cStructure && !m_owner)
+ {
+ memcpy(m_cStructure, &right, sizeof(C_STRUCT));
+ }
+ else
+ {
+ if (m_owner)
+ delete m_cStructure;
+ m_owner = true;
+ m_cStructure = new C_STRUCT(*right);
+ }
+ return *this;
+ }
+
+ virtual ~CStructHdl()
+ {
+ if (m_owner)
+ delete m_cStructure;
+ }
+
+ operator C_STRUCT*() { return m_cStructure; }
+ operator const C_STRUCT*() const { return m_cStructure; }
+
+ const C_STRUCT* GetCStructure() const { return m_cStructure; }
+
+protected:
+ C_STRUCT* m_cStructure = nullptr;
+
+private:
+ bool m_owner = false;
+};
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon_addonbase_Defs
+/// @defgroup cpp_kodi_addon_addonbase_Defs_CSettingValue class CSettingValue
+/// @brief **Setting value handler**\n
+/// Inside addon main instance used helper class to give settings value.
+///
+/// This is used on @ref addon::CAddonBase::SetSetting() to inform addon about
+/// settings change by used. This becomes then used to give the related value
+/// name.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_addonbase_Defs_CSettingValue_Help
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Here is a code example how this is used:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/AddonBase.h>
+///
+/// enum myEnumValue
+/// {
+/// valueA,
+/// valueB,
+/// valueC
+/// };
+///
+/// std::string m_myStringValue;
+/// int m_myIntegerValue;
+/// bool m_myBooleanValue;
+/// float m_myFloatingPointValue;
+/// myEnumValue m_myEnumValue;
+///
+///
+/// ADDON_STATUS CMyAddon::SetSetting(const std::string& settingName, const kodi::addon::CSettingValue& settingValue)
+/// {
+/// if (settingName == "my_string_value")
+/// m_myStringValue = settingValue.GetString();
+/// else if (settingName == "my_integer_value")
+/// m_myIntegerValue = settingValue.GetInt();
+/// else if (settingName == "my_boolean_value")
+/// m_myBooleanValue = settingValue.GetBoolean();
+/// else if (settingName == "my_float_value")
+/// m_myFloatingPointValue = settingValue.GetFloat();
+/// else if (settingName == "my_enum_value")
+/// m_myEnumValue = settingValue.GetEnum<myEnumValue>();
+/// }
+/// ~~~~~~~~~~~~~
+///
+/// @note The asked type should match the type used on settings.xml.
+///
+///@{
+class ATTR_DLL_LOCAL CSettingValue
+{
+public:
+ explicit CSettingValue(const std::string& settingValue) : str(settingValue) {}
+
+ bool empty() const { return str.empty(); }
+
+ /// @defgroup cpp_kodi_addon_addonbase_Defs_CSettingValue_Help Value Help
+ /// @ingroup cpp_kodi_addon_addonbase_Defs_CSettingValue
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_addonbase_Defs_CSettingValue :</b>
+ /// | Name | Type | Get call
+ /// |------|------|----------
+ /// | **Settings value as string** | `std::string` | @ref CSettingValue::GetString "GetString"
+ /// | **Settings value as integer** | `int` | @ref CSettingValue::GetInt "GetInt"
+ /// | **Settings value as unsigned integer** | `unsigned int` | @ref CSettingValue::GetUInt "GetUInt"
+ /// | **Settings value as boolean** | `bool` | @ref CSettingValue::GetBoolean "GetBoolean"
+ /// | **Settings value as floating point** | `float` | @ref CSettingValue::GetFloat "GetFloat"
+ /// | **Settings value as enum** | `enum` | @ref CSettingValue::GetEnum "GetEnum"
+
+ /// @addtogroup cpp_kodi_addon_addonbase_Defs_CSettingValue
+ ///@{
+
+ /// @brief To get settings value as string.
+ std::string GetString() const { return str; }
+
+ /// @brief To get settings value as integer.
+ int GetInt() const { return std::atoi(str.c_str()); }
+
+ /// @brief To get settings value as unsigned integer.
+ unsigned int GetUInt() const { return std::atoi(str.c_str()); }
+
+ /// @brief To get settings value as boolean.
+ bool GetBoolean() const { return std::atoi(str.c_str()) > 0; }
+
+ /// @brief To get settings value as floating point.
+ float GetFloat() const { return static_cast<float>(std::atof(str.c_str())); }
+
+ /// @brief To get settings value as enum.
+ /// @note Inside settings.xml them stored as integer.
+ template<typename enumType>
+ enumType GetEnum() const
+ {
+ return static_cast<enumType>(GetInt());
+ }
+
+ ///@}
+
+private:
+ const std::string str;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon_addonbase_Defs
+/// @defgroup cpp_kodi_addon_addonbase_Defs_IInstanceInfo class IInstanceInfo
+/// @brief **Instance informations**\n
+/// Class to get any instance information when creating a new one.
+///
+///@{
+class ATTR_DLL_LOCAL IInstanceInfo
+{
+public:
+ explicit IInstanceInfo(KODI_ADDON_INSTANCE_STRUCT* instance) : m_instance(instance) {}
+
+ /// @defgroup cpp_kodi_addon_addonbase_Defs_IInstanceInfo_Help Value Help
+ /// @ingroup cpp_kodi_addon_addonbase_Defs_IInstanceInfo
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_addonbase_Defs_IInstanceInfo :</b>
+ /// | Name | Type | Get call
+ /// |------|------|----------
+ /// | **Used type identifier** | @ref KODI_ADDON_INSTANCE_TYPE | @ref CSettingValue::GetType "GetType"
+ /// | **Check asked type used on this class** | `bool` | @ref CSettingValue::IsType "IsType"
+ /// | **Get optional identification number (usage relate to addon type)** | `uint32_t` | @ref CSettingValue::GetNumber "GetNumber"
+ /// | **Get optional identification string (usage relate to addon type)** | `std::string` | @ref CSettingValue::GetID "GetID"
+ /// | **Get API version from Kodi about instance** | `std::string` | @ref CSettingValue::GetAPIVersion "GetAPIVersion"
+ /// | **Check this is first created instance by Kodi** | `bool` | @ref CSettingValue::FirstInstance "FirstInstance"
+
+ /// @addtogroup cpp_kodi_addon_addonbase_Defs_IInstanceInfo
+ ///@{
+
+ /// @brief To get settings value as string.
+ KODI_ADDON_INSTANCE_TYPE GetType() const { return m_instance->info->type; }
+
+ /// @brief Check asked type used on this class.
+ ///
+ /// @param[in] type Type identifier to check
+ /// @return True if type matches
+ bool IsType(KODI_ADDON_INSTANCE_TYPE type) const { return m_instance->info->type == type; }
+
+ /// @brief Get optional identification number (usage relate to addon type).
+ uint32_t GetNumber() const { return m_instance->info->number; }
+
+ /// @brief Get optional identification string (usage relate to addon type).
+ std::string GetID() const { return m_instance->info->id; }
+
+ /// @brief Get API version from Kodi about instance.
+ std::string GetAPIVersion() const { return m_instance->info->version; }
+
+ /// @brief Check this is first created instance by Kodi.
+ bool FirstInstance() const { return m_instance->info->first_instance; }
+
+ ///@}
+
+ operator KODI_ADDON_INSTANCE_STRUCT*() { return m_instance; }
+
+ operator KODI_ADDON_INSTANCE_STRUCT*() const { return m_instance; }
+
+private:
+ IInstanceInfo() = delete;
+ IInstanceInfo(const IInstanceInfo&) = delete;
+
+ KODI_ADDON_INSTANCE_STRUCT* m_instance;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/*
+ * Internal class to control various instance types with general parts defined
+ * here.
+ *
+ * Mainly is this currently used to identify requested instance types.
+ *
+ * @note This class is not need to know during add-on development thats why
+ * commented with "*".
+ */
+class ATTR_DLL_LOCAL IAddonInstance
+{
+public:
+ explicit IAddonInstance(const kodi::addon::IInstanceInfo& instance) : m_instance(instance)
+ {
+ m_instance->functions->instance_setting_change_string = INSTANCE_instance_setting_change_string;
+ m_instance->functions->instance_setting_change_integer =
+ INSTANCE_instance_setting_change_integer;
+ m_instance->functions->instance_setting_change_boolean =
+ INSTANCE_instance_setting_change_boolean;
+ m_instance->functions->instance_setting_change_float = INSTANCE_instance_setting_change_float;
+ }
+ virtual ~IAddonInstance() = default;
+
+ virtual ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ KODI_ADDON_INSTANCE_HDL& hdl)
+ {
+ return ADDON_STATUS_NOT_IMPLEMENTED;
+ }
+
+ std::string GetInstanceAPIVersion() const { return m_instance->info->version; }
+
+ virtual ADDON_STATUS SetInstanceSetting(const std::string& settingName,
+ const kodi::addon::CSettingValue& settingValue)
+ {
+ return ADDON_STATUS_UNKNOWN;
+ }
+
+ inline bool IsInstanceSettingUsingDefault(const std::string& settingName)
+ {
+ return m_instance->info->functions->is_instance_setting_using_default(m_instance->info->kodi,
+ settingName.c_str());
+ }
+
+ inline std::string GetInstanceUserPath(const std::string& append = "")
+ {
+ using namespace kodi::addon;
+
+ char* str = m_instance->info->functions->get_instance_user_path(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ std::string ret = str;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ str);
+ if (!append.empty())
+ {
+ if (append.at(0) != '\\' && append.at(0) != '/')
+#ifdef TARGET_WINDOWS
+ ret.append("\\");
+#else
+ ret.append("/");
+#endif
+ ret.append(append);
+ }
+ return ret;
+ }
+
+ inline bool CheckInstanceSettingString(const std::string& settingName, std::string& settingValue)
+ {
+ char* buffer = nullptr;
+ bool ret = m_instance->info->functions->get_instance_setting_string(
+ m_instance->info->kodi, settingName.c_str(), &buffer);
+ if (buffer)
+ {
+ if (ret)
+ settingValue = buffer;
+ free(buffer);
+ }
+ return ret;
+ }
+
+ inline std::string GetInstanceSettingString(const std::string& settingName,
+ const std::string& defaultValue = "")
+ {
+ std::string settingValue = defaultValue;
+ CheckInstanceSettingString(settingName, settingValue);
+ return settingValue;
+ }
+
+ inline void SetInstanceSettingString(const std::string& settingName,
+ const std::string& settingValue)
+ {
+ m_instance->info->functions->set_instance_setting_string(
+ m_instance->info->kodi, settingName.c_str(), settingValue.c_str());
+ }
+
+ inline bool CheckInstanceSettingInt(const std::string& settingName, int& settingValue)
+ {
+ KODI_ADDON_INSTANCE_FUNC_CB* cb = m_instance->info->functions;
+ return cb->get_instance_setting_int(m_instance->info->kodi, settingName.c_str(), &settingValue);
+ }
+
+ inline int GetInstanceSettingInt(const std::string& settingName, int defaultValue = 0)
+ {
+ int settingValue = defaultValue;
+ CheckInstanceSettingInt(settingName, settingValue);
+ return settingValue;
+ }
+
+ inline void SetInstanceSettingInt(const std::string& settingName, int settingValue)
+ {
+ m_instance->info->functions->set_instance_setting_int(m_instance->info->kodi,
+ settingName.c_str(), settingValue);
+ }
+
+ inline bool CheckInstanceSettingBoolean(const std::string& settingName, bool& settingValue)
+ {
+ return m_instance->info->functions->get_instance_setting_bool(
+ m_instance->info->kodi, settingName.c_str(), &settingValue);
+ }
+
+ inline bool GetInstanceSettingBoolean(const std::string& settingName, bool defaultValue = false)
+ {
+ bool settingValue = defaultValue;
+ CheckInstanceSettingBoolean(settingName, settingValue);
+ return settingValue;
+ }
+
+ inline void SetInstanceSettingBoolean(const std::string& settingName, bool settingValue)
+ {
+ m_instance->info->functions->set_instance_setting_bool(m_instance->info->kodi,
+ settingName.c_str(), settingValue);
+ }
+
+ inline bool CheckInstanceSettingFloat(const std::string& settingName, float& settingValue)
+ {
+ return m_instance->info->functions->get_instance_setting_float(
+ m_instance->info->kodi, settingName.c_str(), &settingValue);
+ }
+
+ inline float GetInstanceSettingFloat(const std::string& settingName, float defaultValue = 0.0f)
+ {
+ float settingValue = defaultValue;
+ CheckInstanceSettingFloat(settingName, settingValue);
+ return settingValue;
+ }
+
+ inline void SetInstanceSettingFloat(const std::string& settingName, float settingValue)
+ {
+ m_instance->info->functions->set_instance_setting_float(m_instance->info->kodi,
+ settingName.c_str(), settingValue);
+ }
+
+ template<typename enumType>
+ inline bool CheckInstanceSettingEnum(const std::string& settingName, enumType& settingValue)
+ {
+ using namespace kodi::addon;
+
+ int settingValueInt = static_cast<int>(settingValue);
+ bool ret = m_instance->info->functions->get_instance_setting_int(
+ m_instance->info->kodi, settingName.c_str(), &settingValueInt);
+ if (ret)
+ settingValue = static_cast<enumType>(settingValueInt);
+ return ret;
+ }
+
+ template<typename enumType>
+ inline enumType GetInstanceSettingEnum(const std::string& settingName,
+ enumType defaultValue = static_cast<enumType>(0))
+ {
+ enumType settingValue = defaultValue;
+ CheckInstanceSettingEnum(settingName, settingValue);
+ return settingValue;
+ }
+
+ template<typename enumType>
+ inline void SetInstanceSettingEnum(const std::string& settingName, enumType settingValue)
+ {
+ m_instance->info->functions->set_instance_setting_int(
+ m_instance->info->kodi, settingName.c_str(), static_cast<int>(settingValue));
+ }
+
+private:
+ static inline ADDON_STATUS INSTANCE_instance_setting_change_string(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, const char* value)
+ {
+ return static_cast<IAddonInstance*>(hdl)->SetInstanceSetting(name, CSettingValue(value));
+ }
+
+ static inline ADDON_STATUS INSTANCE_instance_setting_change_boolean(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, bool value)
+ {
+ return static_cast<IAddonInstance*>(hdl)->SetInstanceSetting(name,
+ CSettingValue(value ? "1" : "0"));
+ }
+
+ static inline ADDON_STATUS INSTANCE_instance_setting_change_integer(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, int value)
+ {
+ return static_cast<IAddonInstance*>(hdl)->SetInstanceSetting(
+ name, CSettingValue(std::to_string(value)));
+ }
+
+ static inline ADDON_STATUS INSTANCE_instance_setting_change_float(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, float value)
+ {
+ return static_cast<IAddonInstance*>(hdl)->SetInstanceSetting(
+ name, CSettingValue(std::to_string(value)));
+ }
+
+ friend class CAddonBase;
+
+ const KODI_ADDON_INSTANCE_STRUCT* m_instance;
+};
+
+//============================================================================
+/// @addtogroup cpp_kodi_addon_addonbase
+/// @brief **Add-on main instance class**\n
+/// This is the addon main class, similar to an <b>`int main()`</b> in executable and
+/// carries out initial work and later management of it.
+///
+class ATTR_DLL_LOCAL CAddonBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_addonbase
+ /// @brief Addon base class constructor.
+ ///
+ CAddonBase()
+ {
+ CPrivateBase::m_interface->toAddon->create = nullptr;
+ CPrivateBase::m_interface->toAddon->destroy = ADDONBASE_Destroy;
+ CPrivateBase::m_interface->toAddon->create_instance = ADDONBASE_CreateInstance;
+ CPrivateBase::m_interface->toAddon->destroy_instance = ADDONBASE_DestroyInstance;
+ CPrivateBase::m_interface->toAddon->setting_change_string = ADDONBASE_setting_change_string;
+ CPrivateBase::m_interface->toAddon->setting_change_boolean = ADDONBASE_setting_change_boolean;
+ CPrivateBase::m_interface->toAddon->setting_change_integer = ADDONBASE_setting_change_integer;
+ CPrivateBase::m_interface->toAddon->setting_change_float = ADDONBASE_setting_change_float;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_addonbase
+ /// @brief Destructor.
+ ///
+ virtual ~CAddonBase() = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_addonbase
+ /// @brief Main addon creation function
+ ///
+ /// With this function addon can carry out necessary work which is required
+ /// at later points or start necessary processes.
+ ///
+ /// This function is optional and necessary work can also be carried out
+ /// using @ref CreateInstance (if it concerns any instance types).
+ ///
+ /// @return @ref ADDON_STATUS_OK if correct, for possible errors see
+ /// @ref ADDON_STATUS
+ ///
+ /// @note Terminating the add-on must be carried out using the class destructor
+ /// given by child.
+ ///
+ virtual ADDON_STATUS Create() { return ADDON_STATUS_OK; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_addonbase
+ /// @brief To inform addon about changed settings values.
+ ///
+ /// This becomes called for every entry defined inside his settings.xml and
+ /// as **last** call the one where last in xml (to identify end of calls).
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_addonbase_Defs_CSettingValue_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here is a code example how this is used:**
+ ///
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/AddonBase.h>
+ ///
+ /// enum myEnumValue
+ /// {
+ /// valueA,
+ /// valueB,
+ /// valueC
+ /// };
+ ///
+ /// std::string m_myStringValue;
+ /// int m_myIntegerValue;
+ /// bool m_myBooleanValue;
+ /// float m_myFloatingPointValue;
+ /// myEnumValue m_myEnumValue;
+ ///
+ ///
+ /// ADDON_STATUS CMyAddon::SetSetting(const std::string& settingName, const kodi::addon::CSettingValue& settingValue)
+ /// {
+ /// if (settingName == "my_string_value")
+ /// m_myStringValue = settingValue.GetString();
+ /// else if (settingName == "my_integer_value")
+ /// m_myIntegerValue = settingValue.GetInt();
+ /// else if (settingName == "my_boolean_value")
+ /// m_myBooleanValue = settingValue.GetBoolean();
+ /// else if (settingName == "my_float_value")
+ /// m_myFloatingPointValue = settingValue.GetFloat();
+ /// else if (settingName == "my_enum_value")
+ /// m_myEnumValue = settingValue.GetEnum<myEnumValue>();
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ /// @note The asked type should match the type used on settings.xml.
+ ///
+ virtual ADDON_STATUS SetSetting(const std::string& settingName,
+ const kodi::addon::CSettingValue& settingValue)
+ {
+ return ADDON_STATUS_UNKNOWN;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_addonbase
+ /// @brief Instance created
+ ///
+ /// @param[in] instance Instance informations about
+ /// @param[out] hdl The pointer to instance class created in addon.
+ /// Needed to be able to identify them on calls.
+ /// @return @ref ADDON_STATUS_OK if correct, for possible errors see @ref ADDON_STATUS
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here is a code example how this is used:**
+ ///
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/AddonBase.h>
+ ///
+ /// ...
+ ///
+ /// // If you use only one instance in your add-on, can be instanceType and
+ /// // instanceID ignored
+ /// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ /// KODI_ADDON_INSTANCE_HDL& hdl)
+ /// {
+ /// if (instance.IsType(ADDON_INSTANCE_SCREENSAVER))
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my Screensaver");
+ /// hdl = new CMyScreensaver(instance);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// else if (instance.IsType(ADDON_INSTANCE_VISUALIZATION))
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my Visualization");
+ /// hdl = new CMyVisualization(instance);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// else if (...)
+ /// {
+ /// ...
+ /// }
+ /// return ADDON_STATUS_UNKNOWN;
+ /// }
+ ///
+ /// ...
+ ///
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ KODI_ADDON_INSTANCE_HDL& hdl)
+ {
+ return ADDON_STATUS_NOT_IMPLEMENTED;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_addonbase
+ /// @brief Instance destroy
+ ///
+ /// This function is optional and intended to notify addon that the instance
+ /// is terminating.
+ ///
+ /// @param[in] instance Instance informations about
+ /// @param[in] hdl The pointer to instance class created in addon.
+ ///
+ /// @warning This call is only used to inform that the associated instance
+ /// is terminated. The deletion is carried out in the background.
+ ///
+ virtual void DestroyInstance(const IInstanceInfo& instance, const KODI_ADDON_INSTANCE_HDL hdl) {}
+ //--------------------------------------------------------------------------
+
+ /* Background helper for GUI render systems, e.g. Screensaver or Visualization */
+ std::shared_ptr<kodi::gui::IRenderHelper> m_renderHelper;
+
+private:
+ static inline void ADDONBASE_Destroy(const KODI_ADDON_HDL hdl)
+ {
+ delete static_cast<CAddonBase*>(hdl);
+ }
+
+ static inline ADDON_STATUS ADDONBASE_CreateInstance(const KODI_ADDON_HDL hdl,
+ struct KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ CAddonBase* base = static_cast<CAddonBase*>(hdl);
+
+ ADDON_STATUS status = ADDON_STATUS_NOT_IMPLEMENTED;
+
+ /* Check about single instance usage:
+ * 1. The kodi side instance pointer must be equal to first one
+ * 2. The addon side instance pointer must be set
+ * 3. And the requested type must be equal with used add-on class
+ */
+ if (CPrivateBase::m_interface->firstKodiInstance == instance &&
+ CPrivateBase::m_interface->globalSingleInstance &&
+ static_cast<IAddonInstance*>(CPrivateBase::m_interface->globalSingleInstance)
+ ->m_instance->info->type == instance->info->type)
+ {
+ /* The handling here is intended for the case of the add-on only one
+ * instance and this is integrated in the add-on base class.
+ */
+ instance->hdl = CPrivateBase::m_interface->globalSingleInstance;
+ status = ADDON_STATUS_OK;
+ }
+ else
+ {
+ /* Here it should use the CreateInstance instance function to allow
+ * creation of several on one addon.
+ */
+
+ IInstanceInfo instanceInfo(instance);
+
+ /* Check first a parent is defined about (e.g. Codec within inputstream) */
+ if (instance->info->parent != nullptr)
+ status = static_cast<IAddonInstance*>(instance->info->parent)
+ ->CreateInstance(instanceInfo, instance->hdl);
+
+ /* if no parent call the main instance creation function to get it */
+ if (status == ADDON_STATUS_NOT_IMPLEMENTED)
+ {
+ status = base->CreateInstance(instanceInfo, instance->hdl);
+ }
+ }
+
+ if (instance->hdl == nullptr)
+ {
+ if (status == ADDON_STATUS_OK)
+ {
+ CPrivateBase::m_interface->toKodi->addon_log_msg(
+ CPrivateBase::m_interface->toKodi->kodiBase, ADDON_LOG_FATAL,
+ "kodi::addon::CAddonBase CreateInstance returned an "
+ "empty instance pointer, but reported OK!");
+ return ADDON_STATUS_PERMANENT_FAILURE;
+ }
+ else
+ {
+ return status;
+ }
+ }
+
+ if (static_cast<IAddonInstance*>(instance->hdl)->m_instance->info->type != instance->info->type)
+ {
+ CPrivateBase::m_interface->toKodi->addon_log_msg(
+ CPrivateBase::m_interface->toKodi->kodiBase, ADDON_LOG_FATAL,
+ "kodi::addon::CAddonBase CreateInstance difference between given and returned");
+ delete static_cast<IAddonInstance*>(instance->hdl);
+ instance->hdl = nullptr;
+ return ADDON_STATUS_PERMANENT_FAILURE;
+ }
+
+ return status;
+ }
+
+ static inline void ADDONBASE_DestroyInstance(const KODI_ADDON_HDL hdl,
+ struct KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ CAddonBase* base = static_cast<CAddonBase*>(hdl);
+
+ if (CPrivateBase::m_interface->globalSingleInstance == nullptr && instance->hdl != base)
+ {
+ IInstanceInfo instanceInfo(instance);
+ base->DestroyInstance(instanceInfo, instance->hdl);
+ delete static_cast<IAddonInstance*>(instance->hdl);
+ }
+ }
+
+ static inline ADDON_STATUS ADDONBASE_setting_change_string(const KODI_ADDON_HDL hdl,
+ const char* name,
+ const char* value)
+ {
+ return static_cast<CAddonBase*>(hdl)->SetSetting(name, CSettingValue(value));
+ }
+
+ static inline ADDON_STATUS ADDONBASE_setting_change_boolean(const KODI_ADDON_HDL hdl,
+ const char* name,
+ bool value)
+ {
+ return static_cast<CAddonBase*>(hdl)->SetSetting(name, CSettingValue(value ? "1" : "0"));
+ }
+
+ static inline ADDON_STATUS ADDONBASE_setting_change_integer(const KODI_ADDON_HDL hdl,
+ const char* name,
+ int value)
+ {
+ return static_cast<CAddonBase*>(hdl)->SetSetting(name, CSettingValue(std::to_string(value)));
+ }
+
+ static inline ADDON_STATUS ADDONBASE_setting_change_float(const KODI_ADDON_HDL hdl,
+ const char* name,
+ float value)
+ {
+ return static_cast<CAddonBase*>(hdl)->SetSetting(name, CSettingValue(std::to_string(value)));
+ }
+};
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief To get the addon system installation folder.
+///
+/// @param[in] append [optional] Path to append to given string
+/// @return Path where addon is installed
+///
+inline std::string ATTR_DLL_LOCAL GetAddonPath(const std::string& append = "")
+{
+ using namespace kodi::addon;
+
+ char* str = CPrivateBase::m_interface->toKodi->kodi_addon->get_addon_path(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ std::string ret = str;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase, str);
+ if (!append.empty())
+ {
+ if (append.at(0) != '\\' && append.at(0) != '/')
+#ifdef TARGET_WINDOWS
+ ret.append("\\");
+#else
+ ret.append("/");
+#endif
+ ret.append(append);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief This function gives OS associated executable binary path of the addon.
+///
+/// With some systems this can differ from the addon path at @ref GetAddonPath.
+///
+/// As an example on Linux:
+/// - Addon path is at `/usr/share/kodi/addons/YOUR_ADDON_ID`
+/// - Library path is at `/usr/lib/kodi/addons/YOUR_ADDON_ID`
+///
+/// @note In addition, in this function, for a given folder, the add-on path
+/// itself, but its parent.
+///
+/// @return Kodi's system library path where related addons are installed.
+///
+inline std::string ATTR_DLL_LOCAL GetLibPath(const std::string& append = "")
+{
+ using namespace kodi::addon;
+
+ char* str = CPrivateBase::m_interface->toKodi->kodi_addon->get_lib_path(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ std::string ret = str;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase, str);
+ if (!append.empty())
+ {
+ if (append.at(0) != '\\' && append.at(0) != '/')
+#ifdef TARGET_WINDOWS
+ ret.append("\\");
+#else
+ ret.append("/");
+#endif
+ ret.append(append);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief To get the user-related folder of the addon.
+///
+/// @note This folder is not created automatically and has to be created by the
+/// addon the first time.
+///
+/// @param[in] append [optional] Path to append to given string
+/// @return User path of addon
+///
+inline std::string ATTR_DLL_LOCAL GetUserPath(const std::string& append = "")
+{
+ using namespace kodi::addon;
+
+ char* str = CPrivateBase::m_interface->toKodi->kodi_addon->get_user_path(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ std::string ret = str;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase, str);
+ if (!append.empty())
+ {
+ if (append.at(0) != '\\' && append.at(0) != '/')
+#ifdef TARGET_WINDOWS
+ ret.append("\\");
+#else
+ ret.append("/");
+#endif
+ ret.append(append);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief To get a temporary path for the addon
+///
+/// This gives a temporary path which the addon can use individually for its things.
+///
+/// The content of this folder will be deleted when Kodi is finished!
+///
+/// @param[in] append A string to append to returned temporary path
+/// @return Individual path for the addon
+///
+inline std::string ATTR_DLL_LOCAL GetTempPath(const std::string& append = "")
+{
+ using namespace kodi::addon;
+
+ char* str = CPrivateBase::m_interface->toKodi->kodi_addon->get_temp_path(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ std::string ret = str;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase, str);
+ if (!append.empty())
+ {
+ if (append.at(0) != '\\' && append.at(0) != '/')
+#ifdef TARGET_WINDOWS
+ ret.append("\\");
+#else
+ ret.append("/");
+#endif
+ ret.append(append);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief Returns an addon's localized 'unicode string'.
+///
+/// @param[in] labelId string you want to localize
+/// @param[in] defaultStr [opt] The default message, also helps to identify
+/// the code that is used <em>(default is
+/// <b><c>empty</c></b>)</em>
+/// @return The localized message, or default if the add-on
+/// helper fails to return a message
+///
+/// @note Label id's \b 30000 to \b 30999 and \b 32000 to \b 32999 are related
+/// to the add-on's own included strings from
+/// <b>./resources/language/resource.language.??_??/strings.po</b>
+/// All other strings are from Kodi core language files.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string str = kodi::GetLocalizedString(30005, "Use me as default");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetLocalizedString(uint32_t labelId,
+ const std::string& defaultStr = "")
+{
+ using namespace kodi::addon;
+
+ std::string retString = defaultStr;
+ char* strMsg = CPrivateBase::m_interface->toKodi->kodi_addon->get_localized_string(
+ CPrivateBase::m_interface->toKodi->kodiBase, labelId);
+ if (strMsg != nullptr)
+ {
+ if (std::strlen(strMsg))
+ retString = strMsg;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ strMsg);
+ }
+ return retString;
+}
+//------------------------------------------------------------------------------
+
+
+//##############################################################################
+/// @ingroup cpp_kodi_addon
+/// @defgroup cpp_kodi_settings 1. Setting control
+/// @brief **Functions to handle settings access**\n
+/// This can be used to get and set the addon related values inside his
+/// settings.xml.
+///
+/// The settings style is given with installed part on e.g.
+/// <b>`$HOME/.kodi/addons/myspecial.addon/resources/settings.xml`</b>. The
+/// related edit becomes then stored inside
+/// <b>`$HOME/.kodi/userdata/addon_data/myspecial.addon/settings.xml`</b>.
+///
+/*!@{*/
+
+//==============================================================================
+/// @brief Opens this Add-Ons settings dialog.
+///
+/// @return true if settings were changed and the dialog confirmed, false otherwise.
+///
+///
+/// --------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ..
+/// kodi::OpenSettings();
+/// ..
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL OpenSettings()
+{
+ using namespace kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_addon->open_settings_dialog(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Check the given setting name is set to default value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @return true if setting is the default
+///
+inline bool ATTR_DLL_LOCAL IsSettingUsingDefault(const std::string& settingName)
+{
+ using namespace kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_addon->is_setting_using_default(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Check and get a string setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[out] settingValue The given setting value
+/// @return true if setting was successfully found and "settingValue" is set
+///
+/// @note If returns false, the "settingValue" is not changed.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// std::string value;
+/// if (!kodi::CheckSettingString("my_string_value", value))
+/// value = "my_default_if_setting_not_work";
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL CheckSettingString(const std::string& settingName,
+ std::string& settingValue)
+{
+ using namespace kodi::addon;
+
+ char* buffer = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_addon->get_setting_string(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), &buffer);
+ if (buffer)
+ {
+ if (ret)
+ settingValue = buffer;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ buffer);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Get string setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[in] defaultValue [opt] Default value if not found
+/// @return The value of setting, empty if not found;
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// std::string value = kodi::GetSettingString("my_string_value");
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetSettingString(const std::string& settingName,
+ const std::string& defaultValue = "")
+{
+ std::string settingValue = defaultValue;
+ CheckSettingString(settingName, settingValue);
+ return settingValue;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Set string setting of addon.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of setting
+/// @param[in] settingValue The setting value to write
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// std::string value = "my_new_name for";
+/// kodi::SetSettingString("my_string_value", value);
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL SetSettingString(const std::string& settingName,
+ const std::string& settingValue)
+{
+ using namespace kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi_addon->set_setting_string(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Check and get a integer setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[out] settingValue The given setting value
+/// @return true if setting was successfully found and "settingValue" is set
+///
+/// @note If returns false, the "settingValue" is not changed.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// int value = 0;
+/// if (!kodi::CheckSettingInt("my_integer_value", value))
+/// value = 123; // My default of them
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL CheckSettingInt(const std::string& settingName, int& settingValue)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_addon->get_setting_int(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Get integer setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[in] defaultValue [opt] Default value if not found
+/// @return The value of setting, <b>`0`</b> or defaultValue if not found
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// int value = kodi::GetSettingInt("my_integer_value");
+/// ~~~~~~~~~~~~~
+///
+inline int ATTR_DLL_LOCAL GetSettingInt(const std::string& settingName, int defaultValue = 0)
+{
+ int settingValue = defaultValue;
+ CheckSettingInt(settingName, settingValue);
+ return settingValue;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Set integer setting of addon.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of setting
+/// @param[in] settingValue The setting value to write
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// int value = 123;
+/// kodi::SetSettingInt("my_integer_value", value);
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL SetSettingInt(const std::string& settingName, int settingValue)
+{
+ using namespace kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi_addon->set_setting_int(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Check and get a boolean setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[out] settingValue The given setting value
+/// @return true if setting was successfully found and "settingValue" is set
+///
+/// @note If returns false, the "settingValue" is not changed.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// bool value = false;
+/// if (!kodi::CheckSettingBoolean("my_boolean_value", value))
+/// value = true; // My default of them
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL CheckSettingBoolean(const std::string& settingName, bool& settingValue)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_addon->get_setting_bool(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Get boolean setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[in] defaultValue [opt] Default value if not found
+/// @return The value of setting, <b>`false`</b> or defaultValue if not found
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// bool value = kodi::GetSettingBoolean("my_boolean_value");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetSettingBoolean(const std::string& settingName,
+ bool defaultValue = false)
+{
+ bool settingValue = defaultValue;
+ CheckSettingBoolean(settingName, settingValue);
+ return settingValue;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Set boolean setting of addon.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of setting
+/// @param[in] settingValue The setting value to write
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// bool value = true;
+/// kodi::SetSettingBoolean("my_boolean_value", value);
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL SetSettingBoolean(const std::string& settingName, bool settingValue)
+{
+ using namespace kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi_addon->set_setting_bool(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Check and get a floating point setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[out] settingValue The given setting value
+/// @return true if setting was successfully found and "settingValue" is set
+///
+/// @note If returns false, the "settingValue" is not changed.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// float value = 0.0f;
+/// if (!kodi::CheckSettingBoolean("my_float_value", value))
+/// value = 1.0f; // My default of them
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL CheckSettingFloat(const std::string& settingName, float& settingValue)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_addon->get_setting_float(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Get floating point setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[in] defaultValue [opt] Default value if not found
+/// @return The value of setting, <b>`0.0`</b> or defaultValue if not found
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// float value = kodi::GetSettingFloat("my_float_value");
+/// ~~~~~~~~~~~~~
+///
+inline float ATTR_DLL_LOCAL GetSettingFloat(const std::string& settingName,
+ float defaultValue = 0.0f)
+{
+ float settingValue = defaultValue;
+ CheckSettingFloat(settingName, settingValue);
+ return settingValue;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Set floating point setting of addon.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of setting
+/// @param[in] settingValue The setting value to write
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// float value = 1.0f;
+/// kodi::SetSettingFloat("my_float_value", value);
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL SetSettingFloat(const std::string& settingName, float settingValue)
+{
+ using namespace kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi_addon->set_setting_float(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Check and get a enum setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[out] settingValue The given setting value
+/// @return true if setting was successfully found and "settingValue" is set
+///
+/// @remark The enums are used as integer inside settings.xml.
+/// @note If returns false, the "settingValue" is not changed.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// enum myEnumValue
+/// {
+/// valueA,
+/// valueB,
+/// valueC
+/// };
+///
+/// myEnumValue value;
+/// if (!kodi::CheckSettingEnum<myEnumValue>("my_enum_value", value))
+/// value = valueA; // My default of them
+/// ~~~~~~~~~~~~~
+///
+template<typename enumType>
+inline bool ATTR_DLL_LOCAL CheckSettingEnum(const std::string& settingName, enumType& settingValue)
+{
+ using namespace kodi::addon;
+
+ int settingValueInt = static_cast<int>(settingValue);
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_addon->get_setting_int(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValueInt);
+ if (ret)
+ settingValue = static_cast<enumType>(settingValueInt);
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Get enum setting value.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of asked setting
+/// @param[in] defaultValue [opt] Default value if not found
+/// @return The value of setting, forced to <b>`0`</b> or defaultValue if not found
+///
+/// @remark The enums are used as integer inside settings.xml.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// enum myEnumValue
+/// {
+/// valueA,
+/// valueB,
+/// valueC
+/// };
+///
+/// myEnumValue value = kodi::GetSettingEnum<myEnumValue>("my_enum_value");
+/// ~~~~~~~~~~~~~
+///
+template<typename enumType>
+inline enumType ATTR_DLL_LOCAL GetSettingEnum(const std::string& settingName,
+ enumType defaultValue = static_cast<enumType>(0))
+{
+ enumType settingValue = defaultValue;
+ CheckSettingEnum(settingName, settingValue);
+ return settingValue;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @brief Set enum setting of addon.
+///
+/// The setting name relate to names used in his <b>settings.xml</b> file.
+///
+/// @param[in] settingName The name of setting
+/// @param[in] settingValue The setting value to write
+///
+/// @remark The enums are used as integer inside settings.xml.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// enum myEnumValue
+/// {
+/// valueA,
+/// valueB,
+/// valueC
+/// };
+///
+/// myEnumValue value = valueA;
+/// kodi::SetSettingEnum<myEnumValue>("my_enum_value", value);
+/// ~~~~~~~~~~~~~
+///
+template<typename enumType>
+inline void ATTR_DLL_LOCAL SetSettingEnum(const std::string& settingName, enumType settingValue)
+{
+ using namespace kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi_addon->set_setting_int(
+ CPrivateBase::m_interface->toKodi->kodiBase, settingName.c_str(),
+ static_cast<int>(settingValue));
+}
+//------------------------------------------------------------------------------
+
+/*!@}*/
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief Returns the value of an addon property as a string
+///
+/// @param[in] id id of the property that the module needs to access
+/// | | Choices are | |
+/// |:------------:|:------------:|:------------:|
+/// | author | icon | stars |
+/// | changelog | id | summary |
+/// | description | name | type |
+/// | disclaimer | path | version |
+/// | fanart | profile | |
+///
+/// @return AddOn property as a string
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string addonName = kodi::GetAddonInfo("name");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetAddonInfo(const std::string& id)
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+
+ std::string strReturn;
+ char* strMsg = toKodi->kodi_addon->get_addon_info(toKodi->kodiBase, id.c_str());
+ if (strMsg != nullptr)
+ {
+ if (std::strlen(strMsg))
+ strReturn = strMsg;
+ toKodi->free_string(toKodi->kodiBase, strMsg);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief Returns a function table to a named interface
+///
+/// @return pointer to struct containing interface functions
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// #include <kodi/platform/foo.h>
+/// ...
+/// FuncTable_foo *table = kodi::GetPlatformInfo(foo_name, foo_version);
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline void* GetInterface(const std::string& name, const std::string& version)
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+
+ return toKodi->kodi_addon->get_interface(toKodi->kodiBase, name.c_str(), version.c_str());
+}
+//----------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief To get used version inside Kodi itself about asked type.
+///
+/// This thought to allow a addon a handling of newer addon versions within
+/// older Kodi until the type min version not changed.
+///
+/// @param[in] type The wanted type of @ref ADDON_TYPE to ask
+/// @return The version string about type in MAJOR.MINOR.PATCH style.
+///
+inline std::string ATTR_DLL_LOCAL GetKodiTypeVersion(int type)
+{
+ using namespace kodi::addon;
+
+ char* str = CPrivateBase::m_interface->toKodi->kodi_addon->get_type_version(
+ CPrivateBase::m_interface->toKodi->kodiBase, type);
+ std::string ret = str;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase, str);
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_addon
+/// @brief Get to related @ref ADDON_STATUS a human readable text.
+///
+/// @param[in] status Status value to get name for
+/// @return Wanted name, as "Unknown" if status not known
+///
+inline std::string ATTR_DLL_LOCAL TranslateAddonStatus(ADDON_STATUS status)
+{
+ switch (status)
+ {
+ case ADDON_STATUS_OK:
+ return "OK";
+ case ADDON_STATUS_LOST_CONNECTION:
+ return "Lost Connection";
+ case ADDON_STATUS_NEED_RESTART:
+ return "Need Restart";
+ case ADDON_STATUS_NEED_SETTINGS:
+ return "Need Settings";
+ case ADDON_STATUS_UNKNOWN:
+ return "Unknown error";
+ case ADDON_STATUS_PERMANENT_FAILURE:
+ return "Permanent failure";
+ case ADDON_STATUS_NOT_IMPLEMENTED:
+ return "Not implemented";
+ default:
+ break;
+ }
+ return "Unknown";
+}
+//----------------------------------------------------------------------------
+
+} /* namespace addon */
+
+//==============================================================================
+/// @ingroup cpp_kodi
+/// @brief Add a message to Kodi's log.
+///
+/// @param[in] loglevel The log level of the message.
+/// @param[in] format The format of the message to pass to Kodi.
+/// @param[in] ... Additional text to insert in format text
+///
+///
+/// @note This method uses limited buffer (16k) for the formatted output.
+/// So data, which will not fit into it, will be silently discarded.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// kodi::Log(ADDON_LOG_ERROR, "%s: There is an error occurred!", __func__);
+///
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL Log(const ADDON_LOG loglevel, const char* format, ...)
+{
+ using namespace kodi::addon;
+
+ va_list args;
+ va_start(args, format);
+ const std::string str = kodi::tools::StringUtils::FormatV(format, args);
+ va_end(args);
+ CPrivateBase::m_interface->toKodi->addon_log_msg(CPrivateBase::m_interface->toKodi->kodiBase,
+ loglevel, str.c_str());
+}
+//------------------------------------------------------------------------------
+
+} /* namespace kodi */
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon_addonbase_Defs
+/// @defgroup cpp_kodi_addon_addonbase_Defs_ADDONCREATORAddonClass macro ADDONCREATOR(AddonClass)
+/// @brief **Addon creation macro**\n
+/// This export the three mandatory "C" functions to have available for Kodi.
+///
+/// @note Only this macro can be used on a C++ addon, everything else is done
+/// automatically.
+///
+/// @param[in] AddonClass Used addon class to be exported with CAddonBase as
+/// parent.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+///
+/// #include <kodi/AddonBash.h>
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS Create() override;
+/// };
+///
+/// ADDON_STATUS CMyAddon::Create()
+/// {
+/// // Some work
+///
+/// return ADDON_STATUS_OK;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// ----------------------------------------------------------------------------
+///
+/// As information, the following functions are exported using this macro:
+/// \table_start
+/// \table_h3{ Function, Use, Description }
+/// \table_row3{ <b>`ADDON_Create(KODI_HANDLE addonInterface)`</b>,
+/// \anchor ADDON_Create
+/// _required_,
+/// <b>Addon creation call.</b>
+/// <br>
+/// Like an `int main()` is this the first on addon called place on his start
+/// and create within C++ API related class inside addon.
+/// <br>
+/// @param[in] addonInterface Handle pointer to get Kodi's given table.
+/// There have addon needed values and functions
+/// to Kodi and addon must set his functions there
+/// for Kodi.
+/// @param[in] globalApiVersion This gives the main version @ref ADDON_GLOBAL_VERSION_MAIN
+/// where currently on Kodi's side.<br>
+/// This is unused on addon as there's also other
+/// special callback functions for.<br>
+/// Only thought for future use if needed earlier.
+/// @param[in] unused This is a not used value\, only there to have in case of
+/// need no Major API version increase where break current.
+/// @return @ref ADDON_STATUS_OK if correct\, for possible errors see
+/// @ref ADDON_STATUS.
+/// <p>
+/// }
+/// \table_row3{ <b>`const char* ADDON_GetTypeVersion(int type)`</b>,
+/// \anchor ADDON_GetTypeVersion
+/// _required_,
+/// <b>Ask addon about version of given type.</b>
+/// <br>
+/// This is used to query its associated version in the addon before work
+/// is carried out in it and the Kodi can adapt to it.
+/// <br>
+/// @param[in] type With @ref ADDON_TYPE defined type to ask.
+/// @return Version as string of asked type.
+/// <p>
+/// }
+/// \table_row3{ <b>`const char* ADDON_GetTypeMinVersion(int type)`</b>,
+/// \anchor ADDON_GetTypeMinVersion
+/// _optional_,
+/// <b>Ask addon about minimal version of given type.</b>
+/// <br>
+/// This is used to query its associated min version in the addon before work
+/// is carried out in it and the Kodi can adapt to it.
+/// <br>
+/// @note The minimum version is optional\, if it were not available\, the
+/// major version is used instead.
+/// <br>
+/// @param[in] type With @ref ADDON_TYPE defined type to ask.
+/// @return Min version as string of asked type.
+/// <p>
+/// }
+/// \table_end
+///
+#define ADDONCREATOR(AddonClass) \
+ extern "C" ATTR_DLL_EXPORT ADDON_STATUS ADDON_Create(KODI_HANDLE addonInterface) \
+ { \
+ using namespace kodi::addon; \
+ CPrivateBase::m_interface = static_cast<AddonGlobalInterface*>(addonInterface); \
+ CPrivateBase::m_interface->addonBase = new AddonClass; \
+ return static_cast<CAddonBase*>(CPrivateBase::m_interface->addonBase)->Create(); \
+ } \
+ extern "C" ATTR_DLL_EXPORT const char* ADDON_GetTypeVersion(int type) \
+ { \
+ return kodi::addon::GetTypeVersion(type); \
+ } \
+ extern "C" ATTR_DLL_EXPORT const char* ADDON_GetTypeMinVersion(int type) \
+ { \
+ return kodi::addon::GetTypeMinVersion(type); \
+ } \
+ AddonGlobalInterface* kodi::addon::CPrivateBase::m_interface = nullptr;
+//------------------------------------------------------------------------------
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/AudioEngine.h b/xbmc/addons/kodi-dev-kit/include/kodi/AudioEngine.h
new file mode 100644
index 0000000..2afe351
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/AudioEngine.h
@@ -0,0 +1,619 @@
+/*
+ * Copyright (C) 2005-2019 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.
+ */
+
+#pragma once
+
+#include "AddonBase.h"
+#include "c-api/audio_engine.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace audioengine
+{
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// Main page text for audio engine group by Doxygen.
+//{{{
+
+//==============================================================================
+///
+/// @defgroup cpp_kodi_audioengine Interface - kodi::audioengine
+/// @ingroup cpp
+/// @brief **Audio engine functions**\n
+/// This interface contains auxiliary functions and classes which allow an addon
+/// to play their own individual audio stream in Kodi.
+///
+/// Using @ref cpp_kodi_audioengine_CAEStream "kodi::audioengine::CAEStream",
+/// a class can be created in this regard, about which the necessary stream data and
+/// information are given to Kodi.
+///
+/// Via @ref kodi::audioengine::GetCurrentSinkFormat(), the audio formats currently
+/// processed in Kodi can be called up beforehand in order to adapt your own stream
+/// to them.
+///
+/// However, the created stream can also differ from this because Kodi changes
+/// it to suit it.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+///
+/// #include <kodi/AudioEngine.h>
+///
+/// ...
+///
+/// kodi::audioengine::AudioEngineFormat format;
+/// if (!kodi::audioengine::GetCurrentSinkFormat(format))
+/// return false;
+///
+/// format.SetDataFormat(AUDIOENGINE_FMT_FLOATP);
+/// format.SetChannelLayout(std::vector<AudioEngineChannel>(AUDIOENGINE_CH_FL, AUDIOENGINE_CH_FR));
+///
+/// unsigned int myUsedSampleRate = format.GetSampleRate();
+///
+/// ...
+///
+/// kodi::audioengine::CAEStream* stream = new kodi::audioengine::CAEStream(format, AUDIO_STREAM_AUTOSTART);
+///
+/// ~~~~~~~~~~~~~
+///
+/// ------------------------------------------------------------------------
+///
+/// It has the header @ref AudioEngine.h "#include <kodi/AudioEngine.h>" be included
+/// to enjoy it.
+///
+//------------------------------------------------------------------------------
+
+//==============================================================================
+///
+/// @defgroup cpp_kodi_audioengine_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_audioengine
+/// @brief **Library definition values**\n
+/// All audio engine functions associated data structures.
+///
+//------------------------------------------------------------------------------
+
+//}}}
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" related audio engine definitions
+//{{{
+
+//==============================================================================
+/// @defgroup cpp_kodi_audioengine_Defs_AudioEngineFormat class AudioEngineFormat
+/// @ingroup cpp_kodi_audioengine_Defs
+/// @brief **Audio format structure**\n
+/// The audio format structure that fully defines a stream's audio
+/// information.
+///
+/// With the help of this format information, Kodi adjusts its processing
+/// accordingly.
+///
+///@{
+class ATTR_DLL_LOCAL AudioEngineFormat
+ : public addon::CStructHdl<AudioEngineFormat, AUDIO_ENGINE_FORMAT>
+{
+public:
+ /*! \cond PRIVATE */
+ AudioEngineFormat()
+ {
+ m_cStructure->m_dataFormat = AUDIOENGINE_FMT_INVALID;
+ m_cStructure->m_sampleRate = 0;
+ m_cStructure->m_encodedRate = 0;
+ m_cStructure->m_frames = 0;
+ m_cStructure->m_frameSize = 0;
+ m_cStructure->m_channelCount = 0;
+
+ for (size_t ch = 0; ch < AUDIOENGINE_CH_MAX; ++ch)
+ m_cStructure->m_channels[ch] = AUDIOENGINE_CH_NULL;
+ }
+ AudioEngineFormat(const AudioEngineFormat& channel) : CStructHdl(channel) {}
+ AudioEngineFormat(const AUDIO_ENGINE_FORMAT* channel) : CStructHdl(channel) {}
+ AudioEngineFormat(AUDIO_ENGINE_FORMAT* channel) : CStructHdl(channel) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_audioengine_Defs_AudioEngineFormat_Help *Value Help*
+ /// @ingroup cpp_kodi_audioengine_Defs_AudioEngineFormat
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_audioengine_Defs_AudioEngineFormat :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Data format**, see @ref AudioEngineDataFormat for available types | enum | @ref AudioEngineFormat::SetDataFormat "SetDataFormat" | @ref AudioEngineFormat::GetDataFormat "GetDataFormat"
+ /// | **Sample rate** | unsigned int | @ref AudioEngineFormat::SetSampleRate "SetSampleRate" | @ref AudioEngineFormat::GetSampleRate "GetSampleRate"
+ /// | **Encoded rate** | unsigned int | @ref AudioEngineFormat::SetEncodedRate "SetEncodedRate" | @ref AudioEngineFormat::GetEncodedRate "GetEncodedRate"
+ /// | **Channel layout**, see @ref AudioEngineChannel for available types | std::vector<enum AudioEngineChannel> | @ref AudioEngineFormat::SetChannelLayout "SetChannelLayout" | @ref AudioEngineFormat::GetChannelLayout "GetChannelLayout"
+ /// | **Frames amount** | unsigned int | @ref AudioEngineFormat::SetFramesAmount "SetFramesAmount" | @ref AudioEngineFormat::GetFramesAmount "GetFramesAmount"
+ /// | **Frame size** | unsigned int | @ref AudioEngineFormat::SetFrameSize "SetFrameSize" | @ref AudioEngineFormat::GetFrameSize "GetFrameSize"
+ ///
+ /// Further is @ref AudioEngineFormat::CompareFormat "CompareFormat" included to compare this class with another.
+ ///
+
+ /// @addtogroup cpp_kodi_audioengine_Defs_AudioEngineFormat
+ /// @copydetails cpp_kodi_audioengine_Defs_AudioEngineFormat_Help
+ ///@{
+
+ /// @brief The stream's data format (eg, AUDIOENGINE_FMT_S16LE)
+ void SetDataFormat(enum AudioEngineDataFormat format) { m_cStructure->m_dataFormat = format; }
+
+ /// @brief To get with @ref SetDataFormat changed values.
+ enum AudioEngineDataFormat GetDataFormat() const { return m_cStructure->m_dataFormat; }
+
+ /// @brief The stream's sample rate (eg, 48000)
+ void SetSampleRate(unsigned int rate) { m_cStructure->m_sampleRate = rate; }
+
+ /// @brief To get with @ref SetSampleRate changed values.
+ unsigned int GetSampleRate() const { return m_cStructure->m_sampleRate; }
+
+ /// @brief The encoded streams sample rate if a bitstream, otherwise undefined
+ void SetEncodedRate(unsigned int rate) { m_cStructure->m_encodedRate = rate; }
+
+ /// @brief To get with @ref SetEncodedRate changed values.
+ unsigned int GetEncodedRate() const { return m_cStructure->m_encodedRate; }
+
+ /// @brief The stream's channel layout
+ void SetChannelLayout(const std::vector<enum AudioEngineChannel>& layout)
+ {
+ // Reset first all to empty values to AUDIOENGINE_CH_NULL, in case given list is empty
+ m_cStructure->m_channelCount = 0;
+ for (size_t ch = 0; ch < AUDIOENGINE_CH_MAX; ++ch)
+ m_cStructure->m_channels[ch] = AUDIOENGINE_CH_NULL;
+
+ for (size_t ch = 0; ch < layout.size() && ch < AUDIOENGINE_CH_MAX; ++ch)
+ {
+ m_cStructure->m_channels[ch] = layout[ch];
+ m_cStructure->m_channelCount++;
+ }
+ }
+
+ /// @brief To get with @ref SetChannelLayout changed values.
+ std::vector<enum AudioEngineChannel> GetChannelLayout() const
+ {
+ std::vector<enum AudioEngineChannel> channels;
+ for (size_t ch = 0; ch < AUDIOENGINE_CH_MAX; ++ch)
+ {
+ if (m_cStructure->m_channels[ch] == AUDIOENGINE_CH_NULL)
+ break;
+
+ channels.push_back(m_cStructure->m_channels[ch]);
+ }
+ return channels;
+ }
+
+ /// @brief The number of frames per period
+ void SetFramesAmount(unsigned int frames) { m_cStructure->m_frames = frames; }
+
+ /// @brief To get with @ref SetFramesAmount changed values.
+ unsigned int GetFramesAmount() const { return m_cStructure->m_frames; }
+
+ /// @brief The size of one frame in bytes
+ void SetFrameSize(unsigned int frameSize) { m_cStructure->m_frameSize = frameSize; }
+
+ /// @brief To get with @ref SetFrameSize changed values.
+ unsigned int GetFrameSize() const { return m_cStructure->m_frameSize; }
+
+ /// @brief Function to compare the format structure with another
+ bool CompareFormat(const AudioEngineFormat* fmt)
+ {
+ if (!fmt)
+ {
+ return false;
+ }
+
+ if (m_cStructure->m_dataFormat != fmt->m_cStructure->m_dataFormat ||
+ m_cStructure->m_sampleRate != fmt->m_cStructure->m_sampleRate ||
+ m_cStructure->m_encodedRate != fmt->m_cStructure->m_encodedRate ||
+ m_cStructure->m_frames != fmt->m_cStructure->m_frames ||
+ m_cStructure->m_frameSize != fmt->m_cStructure->m_frameSize ||
+ m_cStructure->m_channelCount != fmt->m_cStructure->m_channelCount)
+ {
+ return false;
+ }
+
+ for (unsigned int ch = 0; ch < AUDIOENGINE_CH_MAX; ++ch)
+ {
+ if (fmt->m_cStructure->m_channels[ch] != m_cStructure->m_channels[ch])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ ///@}
+};
+///@}
+//----------------------------------------------------------------------------
+
+//}}}
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" AudioEngine addon interface
+//{{{
+
+//============================================================================
+///
+/// @defgroup cpp_kodi_audioengine_CAEStream class CAEStream
+/// @ingroup cpp_kodi_audioengine
+/// @brief **Audio Engine Stream Class**\n
+/// Class that can be created by the addon in order to be able to transfer
+/// audiostream data processed on the addon to Kodi and output it audibly.
+///
+/// This can create individually several times and performed in different
+/// processes simultaneously.
+///
+/// It has the header @ref AudioEngine.h "#include <kodi/AudioEngine.h>" be
+/// included to enjoy it.
+///
+//----------------------------------------------------------------------------
+class ATTR_DLL_LOCAL CAEStream
+{
+public:
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Constructs new class to a Kodi IAEStream in the format specified.
+ ///
+ /// @param[in] format The data format the incoming audio will be in
+ /// (e.g. @ref AUDIOENGINE_FMT_S16LE)
+ /// @param[in] options [opt] A bit field of stream options (see: enum @ref AudioEngineStreamOptions)
+ ///
+ ///
+ /// ------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_audioengine_Defs_AudioEngineFormat_Help
+ ///
+ /// ------------------------------------------------------------------------
+ ///
+ /// **Bit options to pass (on Kodi by <c>IAE::MakeStream</c>)**
+ ///
+ /// | 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
+ ///
+ ///
+ /// ------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ ///
+ /// #include <kodi/AudioEngine.h>
+ ///
+ /// ...
+ ///
+ /// kodi::audioengine::AudioEngineFormat format;
+ ///
+ /// format.SetDataFormat(AUDIOENGINE_FMT_FLOATP); /* The stream's data format (eg, AUDIOENGINE_FMT_S16LE) */
+ /// format.SetChannelLayout(std::vector<AudioEngineChannel>(AUDIOENGINE_CH_FL, AUDIOENGINE_CH_FR)); /* The stream's channel layout */
+ /// format.SetSampleRate(48000); /* The stream's sample rate (eg, 48000) */
+ /// format.SetFrameSize(sizeof(float)*2); /* The size of one frame in bytes */
+ /// format.SetFramesAmount(882); /* The number of samples in one frame */
+ ///
+ /// kodi::audioengine::CAEStream* stream = new kodi::audioengine::CAEStream(format, AUDIO_STREAM_AUTOSTART);
+ ///
+ /// ~~~~~~~~~~~~~
+ ///
+ CAEStream(AudioEngineFormat& format, unsigned int options = 0)
+ : m_kodiBase(::kodi::addon::CPrivateBase::m_interface->toKodi->kodiBase),
+ m_cb(::kodi::addon::CPrivateBase::m_interface->toKodi->kodi_audioengine)
+ {
+ m_StreamHandle = m_cb->make_stream(m_kodiBase, format, options);
+ if (m_StreamHandle == nullptr)
+ {
+ kodi::Log(ADDON_LOG_FATAL, "CAEStream: make_stream failed!");
+ }
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Class destructor.
+ ///
+ ~CAEStream()
+ {
+ if (m_StreamHandle)
+ {
+ m_cb->free_stream(m_kodiBase, m_StreamHandle);
+ m_StreamHandle = nullptr;
+ }
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns the amount of space available in the stream.
+ ///
+ /// @return The number of bytes AddData will consume
+ ///
+ unsigned int GetSpace() { return m_cb->aestream_get_space(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Add planar or interleaved PCM data to the stream.
+ ///
+ /// @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 [opt] presentation timestamp, default is 0
+ /// @param[in] hasDownmix [opt] set true if downmix is present, default is false
+ /// @param[in] centerMixLevel [opt] level to mix left and right to center default is 1.0
+ /// @return The number of frames consumed
+ ///
+ unsigned int AddData(uint8_t* const* data,
+ unsigned int offset,
+ unsigned int frames,
+ double pts = 0,
+ bool hasDownmix = false,
+ double centerMixLevel = 1.0)
+ {
+ return m_cb->aestream_add_data(m_kodiBase, m_StreamHandle, data, offset, frames, pts,
+ hasDownmix, centerMixLevel);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns the time in seconds that it will take for the next added
+ /// packet to be heard from the speakers.
+ ///
+ /// @return seconds
+ ///
+ double GetDelay() { return m_cb->aestream_get_delay(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns if the stream is buffering.
+ ///
+ /// @return True if the stream is buffering
+ ///
+ bool IsBuffering() { return m_cb->aestream_is_buffering(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns the time in seconds of the stream's cached audio samples.
+ /// Engine buffers excluded.
+ ///
+ /// @return seconds
+ ///
+ double GetCacheTime() { return m_cb->aestream_get_cache_time(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns the total time in seconds of the cache.
+ ///
+ /// @return seconds
+ ///
+ double GetCacheTotal() { return m_cb->aestream_get_cache_total(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Pauses the stream playback.
+ ///
+ void Pause() { return m_cb->aestream_pause(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Resumes the stream after pausing
+ ///
+ void Resume() { return m_cb->aestream_resume(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Start draining the stream.
+ ///
+ /// @param[in] wait [opt] Wait until drain is finished if set to true,
+ /// otherwise it returns direct
+ ///
+ /// @note Once called AddData will not consume more data.
+ ///
+ void Drain(bool wait = true) { return m_cb->aestream_drain(m_kodiBase, m_StreamHandle, wait); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns true if the is stream draining.
+ ///
+ bool IsDraining() { return m_cb->aestream_is_draining(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns true if the is stream has finished draining.
+ ///
+ bool IsDrained() { return m_cb->aestream_is_drained(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Flush all buffers dropping the audio data.
+ ///
+ void Flush() { return m_cb->aestream_flush(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Return the stream's current volume level.
+ ///
+ /// @return The volume level between 0.0 and 1.0
+ ///
+ float GetVolume() { return m_cb->aestream_get_volume(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Set the stream's volume level.
+ ///
+ /// @param[in] volume The new volume level between 0.0 and 1.0
+ ///
+ void SetVolume(float volume)
+ {
+ return m_cb->aestream_set_volume(m_kodiBase, m_StreamHandle, volume);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Gets the stream's volume amplification in linear units.
+ ///
+ /// @return The volume amplification factor between 1.0 and 1000.0
+ ///
+ float GetAmplification() { return m_cb->aestream_get_amplification(m_kodiBase, m_StreamHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Sets the stream's volume amplification in linear units.
+ ///
+ /// @param[in] amplify The volume amplification factor between 1.0 and 1000.0
+ ///
+ void SetAmplification(float amplify)
+ {
+ return m_cb->aestream_set_amplification(m_kodiBase, m_StreamHandle, amplify);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns the size of one audio frame in bytes (channelCount * resolution).
+ ///
+ /// @return The size in bytes of one frame
+ ///
+ unsigned int GetFrameSize() const
+ {
+ return m_cb->aestream_get_frame_size(m_kodiBase, m_StreamHandle);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns the number of channels the stream is configured to accept.
+ ///
+ /// @return The channel count
+ ///
+ unsigned int GetChannelCount() const
+ {
+ return m_cb->aestream_get_channel_count(m_kodiBase, m_StreamHandle);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Returns the stream's sample rate, if the stream is using a dynamic
+ /// sample rate, this value will NOT reflect any changes made by calls to
+ /// SetResampleRatio().
+ ///
+ /// @return The stream's sample rate (eg, 48000)
+ ///
+ unsigned int GetSampleRate() const
+ {
+ return m_cb->aestream_get_sample_rate(m_kodiBase, m_StreamHandle);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Return the data format the stream has been configured with.
+ ///
+ /// @return The stream's data format (eg, AUDIOENGINE_FMT_S16LE)
+ ///
+ AudioEngineDataFormat GetDataFormat() const
+ {
+ return m_cb->aestream_get_data_format(m_kodiBase, m_StreamHandle);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Return the resample ratio.
+ ///
+ /// @note This will return an undefined value if the stream is not resampling.
+ ///
+ /// @return the current resample ratio or undefined if the stream is not resampling
+ ///
+ double GetResampleRatio()
+ {
+ return m_cb->aestream_get_resample_ratio(m_kodiBase, m_StreamHandle);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_audioengine_CAEStream
+ /// @brief Sets the resample ratio.
+ ///
+ /// @note This function may return false if the stream is not resampling, if
+ /// you wish to use this be sure to set the AESTREAM_FORCE_RESAMPLE option.
+ ///
+ /// @param[in] ratio the new sample rate ratio, calculated by
+ /// ((double)desiredRate / (double)GetSampleRate())
+ ///
+ void SetResampleRatio(double ratio)
+ {
+ m_cb->aestream_set_resample_ratio(m_kodiBase, m_StreamHandle, ratio);
+ }
+ //--------------------------------------------------------------------------
+
+private:
+ void* m_kodiBase;
+ AddonToKodiFuncTable_kodi_audioengine* m_cb;
+ AEStreamHandle* m_StreamHandle;
+};
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_audioengine
+/// @brief Get the current sink data format.
+///
+/// @param[in] format Current sink data format. For more details see AudioEngineFormat.
+/// @return Returns true on success, else false.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+///
+/// #include <kodi/AudioEngine.h>
+///
+/// ...
+///
+/// kodi::audioengine::AudioEngineFormat format;
+/// if (!kodi::audioengine::GetCurrentSinkFormat(format))
+/// return false;
+///
+/// std::vector<AudioEngineChannel> layout = format.GetChannelLayout();
+///
+/// ...
+/// return true;
+///
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetCurrentSinkFormat(AudioEngineFormat& format)
+{
+ using namespace kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_audioengine->get_current_sink_format(
+ CPrivateBase::m_interface->toKodi->kodiBase, format);
+}
+//----------------------------------------------------------------------------
+
+//}}}
+
+} // namespace audioengine
+} // namespace kodi
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/CMakeLists.txt
new file mode 100644
index 0000000..5e396b9
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ AddonBase.h
+ AudioEngine.h
+ Filesystem.h
+ General.h
+ Network.h
+ versions.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h b/xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h
new file mode 100644
index 0000000..efba5c0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h
@@ -0,0 +1,2379 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "AddonBase.h"
+#include "c-api/filesystem.h"
+
+#ifdef __cplusplus
+
+#include <cstring>
+#include <map>
+#include <vector>
+
+namespace kodi
+{
+namespace vfs
+{
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// Main page text for filesystem group by Doxygen.
+//{{{
+
+//==============================================================================
+///
+/// @defgroup cpp_kodi_vfs Interface - kodi::vfs
+/// @ingroup cpp
+/// @brief **Virtual filesystem functions**\n
+/// Offers classes and functions for access to the Virtual File Server (VFS)
+/// which you can use to manipulate files and folders.
+///
+/// This system allow the use of ["Special Protocol"](https://kodi.wiki/view/Special_protocol)
+/// where is Kodi's solution to platform dependent directories. Common directory
+/// names are assigned a <b>`special://[name]`</b> path which is passed around
+/// inside Kodi and then translated to the platform specific path before the
+/// operating system sees it. This helps keep most of the platform mess
+/// centralized in the code.\n
+/// To become a correct path back can be @ref TranslateSpecialProtocol() used.
+///
+/// It has the header @ref Filesystem.h "#include <kodi/Filesystem.h>" be
+/// included to enjoy it.
+///
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_vfs
+/// @brief **Virtual file Server definition values**\n
+/// All to VFS system functions associated data structures.
+///
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_Directory 1. Directory functions
+/// @ingroup cpp_kodi_vfs
+/// @brief **Globally available directories related functions**\n
+/// Used to perform typical operations with it.
+///
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_File 2. File functions
+/// @ingroup cpp_kodi_vfs
+/// @brief **Globally available file related functions**\n
+/// Used to perform typical operations with it.
+///
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_General 3. General functions
+/// @ingroup cpp_kodi_vfs
+/// @brief **Other globally available functions**\n
+/// Used to perform typical operations with it.
+///
+//------------------------------------------------------------------------------
+
+//}}}
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" related filesystem definitions
+//{{{
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_Defs_FileStatus class FileStatus
+/// @ingroup cpp_kodi_vfs_Defs
+/// @brief **File information status**\n
+/// Used on kodi::vfs::StatFile() to get detailed information about a file.
+///
+///@{
+class ATTR_DLL_LOCAL FileStatus : public kodi::addon::CStructHdl<FileStatus, STAT_STRUCTURE>
+{
+public:
+ /*! \cond PRIVATE */
+ FileStatus() { memset(m_cStructure, 0, sizeof(STAT_STRUCTURE)); }
+ FileStatus(const FileStatus& channel) : CStructHdl(channel) {}
+ FileStatus(const STAT_STRUCTURE* channel) : CStructHdl(channel) {}
+ FileStatus(STAT_STRUCTURE* channel) : CStructHdl(channel) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_vfs_Defs_FileStatus_Help Value Help
+ /// @ingroup cpp_kodi_vfs_Defs_FileStatus
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_vfs_Defs_FileStatus :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **ID of device containing file** | `uint32_t` | @ref FileStatus::SetDeviceId "SetDeviceId" | @ref FileStatus::GetDeviceId "GetDeviceId"
+ /// | **Represent file serial numbers** | `uint64_t` | @ref FileStatus::SetFileSerialNumber "SetFileSerialNumber" | @ref FileStatus::GetFileSerialNumber "GetFileSerialNumber"
+ /// | **Total size, in bytes** | `uint64_t` | @ref FileStatus::SetSize "SetSize" | @ref FileStatus::GetSize "GetSize"
+ /// | **Time of last access** | `time_t` | @ref FileStatus::SetAccessTime "SetAccessTime" | @ref FileStatus::GetAccessTime "GetAccessTime"
+ /// | **Time of last modification** | `time_t` | @ref FileStatus::SetModificationTime "SetModificationTime" | @ref FileStatus::GetModificationTime "GetModificationTime"
+ /// | **Time of last status change** | `time_t` | @ref FileStatus::SetStatusTime "SetStatusTime" | @ref FileStatus::GetStatusTime "GetStatusTime"
+ /// | **Stat url is a directory** | `bool` | @ref FileStatus::SetIsDirectory "SetIsDirectory" | @ref FileStatus::GetIsDirectory "GetIsDirectory"
+ /// | **Stat url as a symbolic link** | `bool` | @ref FileStatus::SetIsSymLink "SetIsSymLink" | @ref FileStatus::GetIsSymLink "GetIsSymLink"
+ /// | **Stat url as a block special** | `bool` | @ref FileStatus::SetIsBlock "SetIsBlock" | @ref FileStatus::GetIsBlock "GetIsBlock"
+ /// | **Stat url as a character special** | `bool` | @ref FileStatus::SetIsCharacter "SetIsCharacter" | @ref FileStatus::GetIsCharacter "GetIsCharacter"
+ /// | **Stat url as a FIFO special** | `bool` | @ref FileStatus::SetIsFifo "SetIsFifo" | @ref FileStatus::GetIsFifo "GetIsFifo"
+ /// | **Stat url as a regular** | `bool` | @ref FileStatus::SetIsRegular "SetIsRegular" | @ref FileStatus::GetIsRegular "GetIsRegular"
+ /// | **Stat url as a socket** | `bool` | @ref FileStatus::SetIsSocket "SetIsSocket" | @ref FileStatus::GetIsSocket "GetIsSocket"
+ ///
+
+ /// @addtogroup cpp_kodi_vfs_Defs_FileStatus
+ /// @copydetails cpp_kodi_vfs_Defs_FileStatus_Help
+ ///@{
+
+ /// @brief Set ID of device containing file.
+ void SetDeviceId(uint32_t deviceId) { m_cStructure->deviceId = deviceId; }
+
+ /// @brief Get ID of device containing file.
+ uint32_t GetDeviceId() const { return m_cStructure->deviceId; }
+
+ /// @brief Set the file serial number, which distinguishes this file from all other files on the same device.
+ void SetFileSerialNumber(uint64_t fileSerialNumber) { m_cStructure->fileSerialNumber = fileSerialNumber; }
+
+ /// @brief Get the file serial number, which distinguishes this file from all other files on the same device.
+ uint64_t GetFileSerialNumber() const { return m_cStructure->fileSerialNumber; }
+
+ /// @brief Set total size, in bytes.
+ void SetSize(uint64_t size) { m_cStructure->size = size; }
+
+ /// @brief Get total size, in bytes.
+ uint64_t GetSize() const { return m_cStructure->size; }
+
+ /// @brief Set time of last access.
+ void SetAccessTime(time_t accessTime) { m_cStructure->accessTime = accessTime; }
+
+ /// @brief Get time of last access.
+ time_t GetAccessTime() const { return m_cStructure->accessTime; }
+
+ /// @brief Set time of last modification.
+ void SetModificationTime(time_t modificationTime)
+ {
+ m_cStructure->modificationTime = modificationTime;
+ }
+
+ /// @brief Get time of last modification.
+ time_t GetModificationTime() const { return m_cStructure->modificationTime; }
+
+ /// @brief Set time of last status change.
+ void SetStatusTime(time_t statusTime) { m_cStructure->statusTime = statusTime; }
+
+ /// @brief Get time of last status change.
+ time_t GetStatusTime() const { return m_cStructure->statusTime; }
+
+ /// @brief Set the stat url is a directory.
+ void SetIsDirectory(bool isDirectory) { m_cStructure->isDirectory = isDirectory; }
+
+ /// @brief The stat url is a directory if returns true.
+ bool GetIsDirectory() const { return m_cStructure->isDirectory; }
+
+ /// @brief Set stat url as a symbolic link.
+ void SetIsSymLink(bool isSymLink) { m_cStructure->isSymLink = isSymLink; }
+
+ /// @brief Get stat url is a symbolic link.
+ bool GetIsSymLink() const { return m_cStructure->isSymLink; }
+
+ /// @brief Set stat url as a block special.
+ void SetIsBlock(bool isBlock) { m_cStructure->isBlock = isBlock; }
+
+ /// @brief Get stat url is a block special.
+ bool GetIsBlock() const { return m_cStructure->isBlock; }
+
+ /// @brief Set stat url as a character special.
+ void SetIsCharacter(bool isCharacter) { m_cStructure->isCharacter = isCharacter; }
+
+ /// @brief Get stat url is a character special.
+ bool GetIsCharacter() const { return m_cStructure->isCharacter; }
+
+ /// @brief Set stat url as a FIFO special.
+ void SetIsFifo(bool isFifo) { m_cStructure->isFifo = isFifo; }
+
+ /// @brief Get stat url is a FIFO special.
+ bool GetIsFifo() const { return m_cStructure->isFifo; }
+
+ /// @brief Set stat url as a regular.
+ void SetIsRegular(bool isRegular) { m_cStructure->isRegular = isRegular; }
+
+ /// @brief Get stat url is a regular.
+ bool GetIsRegular() const { return m_cStructure->isRegular; }
+
+ /// @brief Set stat url is a socket.
+ void SetIsSocket(bool isSocket) { m_cStructure->isSocket = isSocket; }
+
+ /// @brief Get stat url is a regular.
+ bool GetIsSocket() const { return m_cStructure->isSocket; }
+ ///@}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_Defs_CacheStatus class CacheStatus
+/// @ingroup cpp_kodi_vfs_Defs
+/// @brief **Cache information status**\n
+/// Used on kodi::vfs::CFile::IoControlGetCacheStatus() to get running cache
+/// status of processed stream.
+///
+///@{
+class ATTR_DLL_LOCAL CacheStatus
+ : public kodi::addon::CStructHdl<CacheStatus, VFS_CACHE_STATUS_DATA>
+{
+public:
+ /*! \cond PRIVATE */
+ CacheStatus() { memset(m_cStructure, 0, sizeof(VFS_CACHE_STATUS_DATA)); }
+ CacheStatus(const CacheStatus& channel) : CStructHdl(channel) {}
+ CacheStatus(const VFS_CACHE_STATUS_DATA* channel) : CStructHdl(channel) {}
+ CacheStatus(VFS_CACHE_STATUS_DATA* channel) : CStructHdl(channel) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_vfs_Defs_CacheStatus_Help Value Help
+ /// @ingroup cpp_kodi_vfs_Defs_CacheStatus
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_vfs_Defs_CacheStatus :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Number of bytes cached** | `uint64_t` | @ref CacheStatus::SetForward "SetForward" | @ref CacheStatus::GetForward "GetForward"
+ /// | **Maximum number of bytes per second** | `uint32_t` | @ref CacheStatus::SetMaxRate "SetMaxRate" | @ref CacheStatus::GetMaxRate "GetMaxRate"
+ /// | **Average read rate from source file** | `uint32_t` | @ref CacheStatus::SetCurrentRate "SetCurrentRate" | @ref CacheStatus::GetCurrentRate "GetCurrentRate"
+ /// | **Cache low speed rate detected** | `uint32_t` | @ref CacheStatus::SetLowRate "SetLowRate" | @ref CacheStatus::GetLowRate "GetLowRate"
+ ///
+
+ /// @addtogroup cpp_kodi_vfs_Defs_CacheStatus
+ /// @copydetails cpp_kodi_vfs_Defs_CacheStatus_Help
+ ///@{
+
+ /// @brief Set number of bytes cached forward of current position.
+ void SetForward(uint64_t forward) { m_cStructure->forward = forward; }
+
+ /// @brief Get number of bytes cached forward of current position.
+ uint64_t GetForward() { return m_cStructure->forward; }
+
+ /// @brief Set maximum number of bytes per second cache is allowed to fill.
+ void SetMaxRate(uint32_t maxrate) { m_cStructure->maxrate = maxrate; }
+
+ /// @brief Set maximum number of bytes per second cache is allowed to fill.
+ uint32_t GetMaxRate() { return m_cStructure->maxrate; }
+
+ /// @brief Set number of bytes per second for average read rate from source file since last position change.
+ void SetCurrentRate(uint32_t currate) { m_cStructure->currate = currate; }
+
+ /// @brief Get number of bytes per second for average read rate from source file since last position change.
+ uint32_t GetCurrentRate() { return m_cStructure->currate; }
+
+ /// @brief Set number of bytes per second for low speed rate.
+ void SetLowRate(uint32_t lowrate) { m_cStructure->lowrate = lowrate; }
+
+ /// @brief Get number of bytes per second for low speed rate.
+ uint32_t GetLowRate() { return m_cStructure->lowrate; }
+
+ ///@}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_Defs_HttpHeader class HttpHeader
+/// @ingroup cpp_kodi_vfs_Defs
+/// @brief **HTTP header information**\n
+/// The class used to access HTTP header information and get his information.
+///
+/// Used on @ref kodi::vfs::GetHttpHeader().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_vfs_Defs_HttpHeader_Help
+///
+///@{
+class ATTR_DLL_LOCAL HttpHeader
+{
+public:
+ //==========================================================================
+ /// @brief Http header parser class constructor.
+ ///
+ HttpHeader()
+ {
+ using namespace ::kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi_filesystem->http_header_create(
+ CPrivateBase::m_interface->toKodi->kodiBase, &m_handle);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Class destructor.
+ ///
+ ~HttpHeader()
+ {
+ using namespace ::kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi_filesystem->http_header_free(
+ CPrivateBase::m_interface->toKodi->kodiBase, &m_handle);
+ }
+ //--------------------------------------------------------------------------
+
+ /// @defgroup cpp_kodi_vfs_Defs_HttpHeader_Help Value Help
+ /// @ingroup cpp_kodi_vfs_Defs_HttpHeader
+ ///
+ /// <b>The following table contains values that can be get with @ref cpp_kodi_vfs_Defs_HttpHeader :</b>
+ /// | Description | Type | Get call
+ /// |-------------|------|------------
+ /// | **Get the value associated with this parameter of these HTTP headers** | `std::string` | @ref HttpHeader::GetValue "GetValue"
+ /// | **Get the values as list associated with this parameter of these HTTP headers** | `std::vector<std::string>` | @ref HttpHeader::GetValues "GetValues"
+ /// | **Get the full header string associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetHeader "GetHeader"
+ /// | **Get the mime type associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetMimeType "GetMimeType"
+ /// | **Get the charset associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetCharset "GetCharset"
+ /// | **The protocol line associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetProtoLine "GetProtoLine"
+ ///
+
+ /// @addtogroup cpp_kodi_vfs_Defs_HttpHeader
+ ///@{
+
+ //==========================================================================
+ /// @brief Get the value associated with this parameter of these HTTP
+ /// headers.
+ ///
+ /// @param[in] param The name of the parameter a value is required for
+ /// @return The value found
+ ///
+ std::string GetValue(const std::string& param) const
+ {
+ using namespace ::kodi::addon;
+
+ if (!m_handle.handle)
+ return "";
+
+ std::string protoLine;
+ char* string = m_handle.get_value(CPrivateBase::m_interface->toKodi->kodiBase, m_handle.handle,
+ param.c_str());
+ if (string != nullptr)
+ {
+ protoLine = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return protoLine;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Get the values as list associated with this parameter of these
+ /// HTTP headers.
+ ///
+ /// @param[in] param The name of the parameter values are required for
+ /// @return The values found
+ ///
+ std::vector<std::string> GetValues(const std::string& param) const
+ {
+ using namespace kodi::addon;
+
+ if (!m_handle.handle)
+ return std::vector<std::string>();
+
+ int numValues = 0;
+ char** res(m_handle.get_values(CPrivateBase::m_interface->toKodi->kodiBase, m_handle.handle,
+ param.c_str(), &numValues));
+ if (res)
+ {
+ std::vector<std::string> vecReturn;
+ vecReturn.reserve(numValues);
+ for (int i = 0; i < numValues; ++i)
+ {
+ vecReturn.emplace_back(res[i]);
+ }
+ CPrivateBase::m_interface->toKodi->free_string_array(
+ CPrivateBase::m_interface->toKodi->kodiBase, res, numValues);
+ return vecReturn;
+ }
+ return std::vector<std::string>();
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Get the full header string associated with these HTTP headers.
+ ///
+ /// @return The header as a string
+ ///
+ std::string GetHeader() const
+ {
+ using namespace ::kodi::addon;
+
+ if (!m_handle.handle)
+ return "";
+
+ std::string header;
+ char* string =
+ m_handle.get_header(CPrivateBase::m_interface->toKodi->kodiBase, m_handle.handle);
+ if (string != nullptr)
+ {
+ header = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return header;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Get the mime type associated with these HTTP headers.
+ ///
+ /// @return The mime type
+ ///
+ std::string GetMimeType() const
+ {
+ using namespace ::kodi::addon;
+
+ if (!m_handle.handle)
+ return "";
+
+ std::string protoLine;
+ char* string =
+ m_handle.get_mime_type(CPrivateBase::m_interface->toKodi->kodiBase, m_handle.handle);
+ if (string != nullptr)
+ {
+ protoLine = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return protoLine;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Get the charset associated with these HTTP headers.
+ ///
+ /// @return The charset
+ ///
+ std::string GetCharset() const
+ {
+ using namespace ::kodi::addon;
+
+ if (!m_handle.handle)
+ return "";
+
+ std::string protoLine;
+ char* string =
+ m_handle.get_charset(CPrivateBase::m_interface->toKodi->kodiBase, m_handle.handle);
+ if (string != nullptr)
+ {
+ protoLine = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return protoLine;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief The protocol line associated with these HTTP headers.
+ ///
+ /// @return The protocol line
+ ///
+ std::string GetProtoLine() const
+ {
+ using namespace ::kodi::addon;
+
+ if (!m_handle.handle)
+ return "";
+
+ std::string protoLine;
+ char* string =
+ m_handle.get_proto_line(CPrivateBase::m_interface->toKodi->kodiBase, m_handle.handle);
+ if (string != nullptr)
+ {
+ protoLine = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return protoLine;
+ }
+ //--------------------------------------------------------------------------
+
+ ///@}
+
+ KODI_HTTP_HEADER m_handle;
+};
+///@}
+//----------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_CDirEntry class CDirEntry
+/// @ingroup cpp_kodi_vfs_Defs
+///
+/// @brief **Virtual file server directory entry**\n
+/// This class is used as an entry for files and folders in
+/// kodi::vfs::GetDirectory().
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+///
+/// ...
+///
+/// std::vector<kodi::vfs::CDirEntry> items;
+/// kodi::vfs::GetDirectory("special://temp", "", items);
+///
+/// fprintf(stderr, "Directory have %lu entries\n", items.size());
+/// for (unsigned long i = 0; i < items.size(); i++)
+/// {
+/// char buff[20];
+/// time_t now = items[i].DateTime();
+/// strftime(buff, 20, "%Y-%m-%d %H:%M:%S", gmtime(&now));
+/// fprintf(stderr, " - %04lu -- Folder: %s -- Name: %s -- Path: %s -- Time: %s\n",
+/// i+1,
+/// items[i].IsFolder() ? "yes" : "no ",
+/// items[i].Label().c_str(),
+/// items[i].Path().c_str(),
+/// buff);
+/// }
+/// ~~~~~~~~~~~~~
+///
+/// It has the header @ref Filesystem.h "#include <kodi/Filesystem.h>" be included
+/// to enjoy it.
+///
+///@{
+class ATTR_DLL_LOCAL CDirEntry
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_vfs_CDirEntry
+ /// @brief Constructor for VFS directory entry
+ ///
+ /// @param[in] label [opt] Name to use for entry
+ /// @param[in] path [opt] Used path of the entry
+ /// @param[in] folder [opt] If set entry used as folder
+ /// @param[in] size [opt] If used as file, his size defined there
+ /// @param[in] dateTime [opt] Date time of the entry
+ ///
+ CDirEntry(const std::string& label = "",
+ const std::string& path = "",
+ bool folder = false,
+ int64_t size = -1,
+ time_t dateTime = 0)
+ : m_label(label), m_path(path), m_folder(folder), m_size(size), m_dateTime(dateTime)
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ // @note Not for addon development itself needed, thats why below is
+ // disabled for doxygen!
+ //
+ // @ingroup cpp_kodi_vfs_CDirEntry
+ // @brief Constructor to create own copy
+ //
+ // @param[in] dirEntry pointer to own class type
+ //
+ explicit CDirEntry(const VFSDirEntry& dirEntry)
+ : m_label(dirEntry.label ? dirEntry.label : ""),
+ m_path(dirEntry.path ? dirEntry.path : ""),
+ m_folder(dirEntry.folder),
+ m_size(dirEntry.size),
+ m_dateTime(dirEntry.date_time)
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ /// @defgroup cpp_kodi_vfs_CDirEntry_Help Value Help
+ /// @ingroup cpp_kodi_vfs_CDirEntry
+ /// --------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_vfs_CDirEntry :</b>
+ /// | Name | Type | Set call | Get call | Clear call |
+ /// |------|------|----------|----------|------------|
+ /// | **Directory entry name** | `std::string` | @ref CDirEntry::SetLabel "SetLabel" | @ref CDirEntry::Label "Label" | |
+ /// | **Title of entry** | `std::string` | @ref CDirEntry::SetTitle "SetTitle" | @ref CDirEntry::Title "Title" | |
+ /// | **Path of the entry** | `std::string` | @ref CDirEntry::SetPath "SetPath" | @ref CDirEntry::Path "Path" | |
+ /// | **Entry is folder** | `bool` | @ref CDirEntry::SetFolder "SetFolder" | @ref CDirEntry::IsFolder "IsFolder" | |
+ /// | **The size of the file** | `int64_t` | @ref CDirEntry::SetSize "SetSize" | @ref CDirEntry::Size "Size" | |
+ /// | **File time and date** | `time_t` | @ref CDirEntry::SetDateTime "SetDateTime" | @ref CDirEntry::DateTime "DateTime" | |
+ /// | **Property entries** | `std::string, std::string` | @ref CDirEntry::AddProperty "AddProperty" | @ref CDirEntry::GetProperties "GetProperties" | @ref CDirEntry::ClearProperties "ClearProperties"
+ ///
+
+ /// @addtogroup cpp_kodi_vfs_CDirEntry
+ /// @copydetails cpp_kodi_vfs_CDirEntry_Help
+ ///@{
+
+ //============================================================================
+ /// @brief Get the directory entry name.
+ ///
+ /// @return Name of the entry
+ ///
+ const std::string& Label(void) const { return m_label; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the optional title of entry.
+ ///
+ /// @return Title of the entry, if exists
+ ///
+ const std::string& Title(void) const { return m_title; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the path of the entry.
+ ///
+ /// @return File system path of the entry
+ ///
+ const std::string& Path(void) const { return m_path; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Used to check entry is folder.
+ ///
+ /// @return true if entry is a folder
+ ///
+ bool IsFolder(void) const { return m_folder; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief If file, the size of the file.
+ ///
+ /// @return Defined file size
+ ///
+ int64_t Size(void) const { return m_size; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get file time and date for a new entry.
+ ///
+ /// @return The with time_t defined date and time of file
+ ///
+ time_t DateTime() { return m_dateTime; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the label name.
+ ///
+ /// @param[in] label name of entry
+ ///
+ void SetLabel(const std::string& label) { m_label = label; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the title name.
+ ///
+ /// @param[in] title title name of entry
+ ///
+ void SetTitle(const std::string& title) { m_title = title; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the path of the entry.
+ ///
+ /// @param[in] path path of entry
+ ///
+ void SetPath(const std::string& path) { m_path = path; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the entry defined as folder.
+ ///
+ /// @param[in] folder If true becomes entry defined as folder
+ ///
+ void SetFolder(bool folder) { m_folder = folder; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set a file size for a new entry.
+ ///
+ /// @param[in] size Size to set for dir entry
+ ///
+ void SetSize(int64_t size) { m_size = size; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set file time and date for a new entry.
+ ///
+ /// @param[in] dateTime The with time_t defined date and time of file
+ ///
+ void SetDateTime(time_t dateTime) { m_dateTime = dateTime; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Add a by string defined property entry to directory entry.
+ ///
+ /// @note A property can be used to add some special information about a file
+ /// or directory entry, this can be used on other places to do the right work
+ /// of them.
+ ///
+ /// @param[in] id Identification name of property
+ /// @param[in] value The property value to add by given id
+ ///
+ void AddProperty(const std::string& id, const std::string& value) { m_properties[id] = value; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Clear all present properties.
+ ///
+ void ClearProperties() { m_properties.clear(); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the present properties list on directory entry.
+ ///
+ /// @return map with all present properties
+ ///
+ const std::map<std::string, std::string>& GetProperties() const { return m_properties; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+private:
+ std::string m_label;
+ std::string m_title;
+ std::string m_path;
+ std::map<std::string, std::string> m_properties;
+ bool m_folder;
+ int64_t m_size;
+ time_t m_dateTime;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//}}}
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Directory related functions
+//{{{
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_Directory
+/// @brief Make a directory.
+///
+/// The kodi::vfs::CreateDirectory() function shall create a
+/// new directory with name path.
+///
+/// The newly created directory shall be an empty directory.
+///
+/// @param[in] path Path to the directory.
+/// @return Upon successful completion, CreateDirectory() shall return true.
+/// Otherwise false shall be returned, no directory shall be created.
+///
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string directory = "C:\\my_dir";
+/// bool ret = kodi::vfs::CreateDirectory(directory);
+/// fprintf(stderr, "Directory '%s' successfully created: %s\n", directory.c_str(), ret ? "yes" : "no");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL CreateDirectory(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->create_directory(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_Directory
+/// @brief Verifying the Existence of a Directory.
+///
+/// The kodi::vfs::DirectoryExists() method determines whether
+/// a specified folder exists.
+///
+/// @param[in] path Path to the directory.
+/// @return True when it exists, false otherwise.
+///
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string directory = "C:\\my_dir";
+/// bool ret = kodi::vfs::DirectoryExists(directory);
+/// fprintf(stderr, "Directory '%s' present: %s\n", directory.c_str(), ret ? "yes" : "no");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL DirectoryExists(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->directory_exists(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_Directory
+/// @brief Removes a directory.
+///
+/// The kodi::vfs::RemoveDirectory() function shall remove a
+/// directory whose name is given by path.
+///
+/// @param[in] path Path to the directory.
+/// @param[in] recursive [opt] Remove directory recursive (default is false)
+/// @return Upon successful completion, the function RemoveDirectory() shall
+/// return true. Otherwise, false shall be returned, and errno set
+/// to indicate the error. If false is returned, the named directory
+/// shall not be changed.
+///
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// bool ret = kodi::vfs::RemoveDirectory("C:\\my_dir");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL RemoveDirectory(const std::string& path, bool recursive = false)
+{
+ using namespace kodi::addon;
+
+ if (!recursive)
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->remove_directory(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+ else
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->remove_directory_recursive(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_Directory
+/// @brief Lists a directory.
+///
+/// Return the list of files and directories which have been found in the
+/// specified directory and which respect the given constraint.
+///
+/// It can handle the normal OS dependent paths and also the special virtual
+/// filesystem from Kodi what starts with \b special://.
+///
+/// @param[in] path The path in which the files and directories are located.
+/// @param[in] mask Mask to filter out requested files, e.g. "*.avi|*.mpg" to
+/// files with this ending.
+/// @param[out] items The returned list directory entries.
+/// @return True if listing was successful, false otherwise.
+///
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+///
+/// std::vector<kodi::vfs::CDirEntry> items;
+/// kodi::vfs::GetDirectory("special://temp", "", items);
+///
+/// fprintf(stderr, "Directory have %lu entries\n", items.size());
+/// for (unsigned long i = 0; i < items.size(); i++)
+/// {
+/// fprintf(stderr, " - %04lu -- Folder: %s -- Name: %s -- Path: %s\n",
+/// i+1,
+/// items[i].IsFolder() ? "yes" : "no ",
+/// items[i].Label().c_str(),
+/// items[i].Path().c_str());
+/// }
+/// ~~~~~~~~~~~~~
+inline bool ATTR_DLL_LOCAL GetDirectory(const std::string& path,
+ const std::string& mask,
+ std::vector<kodi::vfs::CDirEntry>& items)
+{
+ using namespace kodi::addon;
+
+ VFSDirEntry* dir_list = nullptr;
+ unsigned int num_items = 0;
+ if (CPrivateBase::m_interface->toKodi->kodi_filesystem->get_directory(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str(), mask.c_str(), &dir_list,
+ &num_items))
+ {
+ if (dir_list)
+ {
+ for (unsigned int i = 0; i < num_items; ++i)
+ items.emplace_back(dir_list[i]);
+
+ CPrivateBase::m_interface->toKodi->kodi_filesystem->free_directory(
+ CPrivateBase::m_interface->toKodi->kodiBase, dir_list, num_items);
+ }
+
+ return true;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+//}}}
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" File related functions
+//{{{
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_File
+/// @brief Check if a file exists.
+///
+/// @param[in] filename The filename to check.
+/// @param[in] usecache Check in file cache.
+/// @return true if the file exists false otherwise.
+///
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// bool exists = kodi::vfs::FileExists("special://temp/kodi.log");
+/// fprintf(stderr, "Log file should be always present, is it present? %s\n", exists ? "yes" : "no");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL FileExists(const std::string& filename, bool usecache = false)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->file_exists(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str(), usecache);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_File
+/// @brief Get file status.
+///
+/// These function return information about a file. Execute (search)
+/// permission is required on all of the directories in path that
+/// lead to the file.
+///
+/// The call return a stat structure, which contains the on
+/// @ref cpp_kodi_vfs_Defs_FileStatus defined values.
+///
+/// @warning Not all of the OS file systems implement all of the time fields.
+///
+/// @param[in] filename The filename to read the status from.
+/// @param[out] buffer The file status is written into this buffer.
+/// @return On success, trur is returned. On error, false is returned
+///
+///
+/// @copydetails cpp_kodi_vfs_Defs_FileStatus_Help
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// kodi::vfs::FileStatus statFile;
+/// int ret = kodi::vfs::StatFile("special://temp/kodi.log", statFile);
+/// fprintf(stderr, "deviceId (ID of device containing file) = %u\n"
+/// "size (total size, in bytes) = %lu\n"
+/// "accessTime (time of last access) = %lu\n"
+/// "modificationTime (time of last modification) = %lu\n"
+/// "statusTime (time of last status change) = %lu\n"
+/// "isDirectory (The stat url is a directory) = %s\n"
+/// "isSymLink (The stat url is a symbolic link) = %s\n"
+/// "Return value = %i\n",
+/// statFile.GetDeviceId(),
+/// statFile.GetSize(),
+/// statFile.GetAccessTime(),
+/// statFile.GetModificationTime(),
+/// statFile.GetStatusTime(),
+/// statFile.GetIsDirectory() ? "true" : "false",
+/// statFile.GetIsSymLink() ? "true" : "false",
+/// ret);
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL StatFile(const std::string& filename, kodi::vfs::FileStatus& buffer)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->stat_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str(), buffer);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_File
+/// @brief Deletes a file.
+///
+/// @param[in] filename The filename to delete.
+/// @return The file was successfully deleted.
+///
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// #include <kodi/gui/DialogFileBrowser.h>
+/// #include <kodi/gui/DialogOK.h>
+/// ...
+/// std::string filename;
+/// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "",
+/// "Test File selection and delete of them!",
+/// filename))
+/// {
+/// bool successed = kodi::vfs::DeleteFile(filename);
+/// if (!successed)
+/// kodi::gui::DialogOK::ShowAndGetInput("Error", "Delete of File", filename, "failed!");
+/// else
+/// kodi::gui::DialogOK::ShowAndGetInput("Information", "Delete of File", filename, "successfully done.");
+/// }
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL DeleteFile(const std::string& filename)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->delete_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_File
+/// @brief Rename a file name.
+///
+/// @param[in] filename The filename to copy.
+/// @param[in] newFileName The new filename
+/// @return true if successfully renamed
+///
+///
+inline bool ATTR_DLL_LOCAL RenameFile(const std::string& filename, const std::string& newFileName)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->rename_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str(), newFileName.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_File
+/// @brief Copy a file from source to destination.
+///
+/// @param[in] filename The filename to copy.
+/// @param[in] destination The destination to copy file to
+/// @return true if successfully copied
+///
+///
+inline bool ATTR_DLL_LOCAL CopyFile(const std::string& filename, const std::string& destination)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->copy_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str(), destination.c_str());
+}
+//------------------------------------------------------------------------------
+
+//}}}
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" General filesystem functions
+//{{{
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Retrieve MD5sum of a file.
+///
+/// @param[in] path Path to the file to MD5sum
+/// @return MD5 sum of the file
+///
+///
+/// -------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// #include <kodi/gui/DialogFileBrowser.h>
+/// ...
+/// std::string md5;
+/// std::string filename;
+/// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "*.avi|*.mpg|*.mp4",
+/// "Test File selection to get MD5",
+/// filename))
+/// {
+/// md5 = kodi::vfs::GetFileMD5(filename);
+/// fprintf(stderr, "MD5 of file '%s' is %s\n", md5.c_str(), filename.c_str());
+/// }
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetFileMD5(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ std::string strReturn;
+ char* strMd5 = CPrivateBase::m_interface->toKodi->kodi_filesystem->get_file_md5(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+ if (strMd5 != nullptr)
+ {
+ if (std::strlen(strMd5))
+ strReturn = strMd5;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ strMd5);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Returns a thumb cache filename.
+///
+/// @param[in] filename Path to file
+/// @return Cache filename
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// #include <kodi/gui/DialogFileBrowser.h>
+/// ...
+/// std::string thumb;
+/// std::string filename;
+/// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "*.avi|*.mpg|*.mp4",
+/// "Test File selection to get Thumnail",
+/// filename))
+/// {
+/// thumb = kodi::vfs::GetCacheThumbName(filename);
+/// fprintf(stderr, "Thumb name of file '%s' is %s\n", thumb.c_str(), filename.c_str());
+/// }
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetCacheThumbName(const std::string& filename)
+{
+ using namespace kodi::addon;
+
+ std::string strReturn;
+ char* strThumbName = CPrivateBase::m_interface->toKodi->kodi_filesystem->get_cache_thumb_name(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str());
+ if (strThumbName != nullptr)
+ {
+ if (std::strlen(strThumbName))
+ strReturn = strThumbName;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ strThumbName);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Make filename valid.
+///
+/// Function to replace not valid characters with '_'. It can be also
+/// compared with original before in a own loop until it is equal
+/// (no invalid characters).
+///
+/// @param[in] filename Filename to check and fix
+/// @return The legal filename
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string fileName = "///\\jk???lj????.mpg";
+/// std::string legalName = kodi::vfs::MakeLegalFileName(fileName);
+/// fprintf(stderr, "Legal name of '%s' is '%s'\n", fileName.c_str(), legalName.c_str());
+///
+/// /* Returns as legal: 'jk___lj____.mpg' */
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL MakeLegalFileName(const std::string& filename)
+{
+ using namespace kodi::addon;
+
+ std::string strReturn;
+ char* strLegalFileName = CPrivateBase::m_interface->toKodi->kodi_filesystem->make_legal_filename(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str());
+ if (strLegalFileName != nullptr)
+ {
+ if (std::strlen(strLegalFileName))
+ strReturn = strLegalFileName;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ strLegalFileName);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Make directory name valid.
+///
+/// Function to replace not valid characters with '_'. It can be also
+/// compared with original before in a own loop until it is equal
+/// (no invalid characters).
+///
+/// @param[in] path Directory name to check and fix
+/// @return The legal directory name
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string path = "///\\jk???lj????\\hgjkg";
+/// std::string legalPath = kodi::vfs::MakeLegalPath(path);
+/// fprintf(stderr, "Legal name of '%s' is '%s'\n", path.c_str(), legalPath.c_str());
+///
+/// /* Returns as legal: '/jk___lj____/hgjkg' */
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL MakeLegalPath(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ std::string strReturn;
+ char* strLegalPath = CPrivateBase::m_interface->toKodi->kodi_filesystem->make_legal_path(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+ if (strLegalPath != nullptr)
+ {
+ if (std::strlen(strLegalPath))
+ strReturn = strLegalPath;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ strLegalPath);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Returns the translated path.
+///
+/// @param[in] source String or unicode - Path to format
+/// @return A human-readable string suitable for logging
+///
+/// @note Only useful if you are coding for both Linux and Windows. e.g.
+/// Converts 'special://masterprofile/script_data' ->
+/// '/home/user/.kodi/UserData/script_data' on Linux.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string path = kodi::vfs::TranslateSpecialProtocol("special://masterprofile/script_data");
+/// fprintf(stderr, "Translated path is: %s\n", path.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+/// or
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// fprintf(stderr, "Directory 'special://temp' is '%s'\n", kodi::vfs::TranslateSpecialProtocol("special://temp").c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL TranslateSpecialProtocol(const std::string& source)
+{
+ using namespace kodi::addon;
+
+ std::string strReturn;
+ char* protocol = CPrivateBase::m_interface->toKodi->kodi_filesystem->translate_special_protocol(
+ CPrivateBase::m_interface->toKodi->kodiBase, source.c_str());
+ if (protocol != nullptr)
+ {
+ if (std::strlen(protocol))
+ strReturn = protocol;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ protocol);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Retrieves information about the amount of space that is available on
+/// a disk volume.
+///
+/// Path can be also with Kodi's special protocol.
+///
+/// @param[in] path Path for where to check
+/// @param[out] capacity The total number of bytes in the file system
+/// @param[out] free The total number of free bytes in the file system
+/// @param[out] available The total number of free bytes available to a
+/// non-privileged process
+/// @return true if successfully done and set
+///
+/// @warning This only works with paths belonging to OS. If <b>"special://"</b>
+/// is used, it must point to a place on your own OS.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <climits> // for ULLONG_MAX
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string path = "special://temp";
+/// uint64_t capacity = ULLONG_MAX;
+/// uint64_t free = ULLONG_MAX;
+/// uint64_t available = ULLONG_MAX;
+/// kodi::vfs::GetDiskSpace(path, capacity, free, available);
+/// fprintf(stderr, "Path '%s' sizes:\n", path.c_str());
+/// fprintf(stderr, " - capacity: %lu MByte\n", capacity / 1024 / 1024);
+/// fprintf(stderr, " - free: %lu MByte\n", free / 1024 / 1024);
+/// fprintf(stderr, " - available: %lu MByte\n", available / 1024 / 1024);
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetDiskSpace(const std::string& path,
+ uint64_t& capacity,
+ uint64_t& free,
+ uint64_t& available)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->get_disk_space(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str(), &capacity, &free, &available);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Return the file name from given complete path string.
+///
+/// @param[in] path The complete path include file and directory
+/// @return Filename from path
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string fileName = kodi::vfs::GetFileName("special://temp/kodi.log");
+/// fprintf(stderr, "File name is '%s'\n", fileName.c_str());
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetFileName(const std::string& path)
+{
+ /* find the last slash */
+ const size_t slash = path.find_last_of("/\\");
+ return path.substr(slash + 1);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Return the directory name from given complete path string.
+///
+/// @param[in] path The complete path include file and directory
+/// @return Directory name from path
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string dirName = kodi::vfs::GetDirectoryName("special://temp/kodi.log");
+/// fprintf(stderr, "Directory name is '%s'\n", dirName.c_str());
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetDirectoryName(const std::string& path)
+{
+ // Will from a full filename return the directory the file resides in.
+ // Keeps the final slash at end and possible |option=foo options.
+
+ size_t iPosSlash = path.find_last_of("/\\");
+ if (iPosSlash == std::string::npos)
+ return ""; // No slash, so no path (ignore any options)
+
+ size_t iPosBar = path.rfind('|');
+ if (iPosBar == std::string::npos)
+ return path.substr(0, iPosSlash + 1); // Only path
+
+ return path.substr(0, iPosSlash + 1) + path.substr(iPosBar); // Path + options
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Remove the slash on given path name.
+///
+/// @param[in,out] path The complete path
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string dirName = "special://temp/";
+/// kodi::vfs::RemoveSlashAtEnd(dirName);
+/// fprintf(stderr, "Directory name is '%s'\n", dirName.c_str());
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL 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_General
+/// @brief Return a size aligned to the chunk size at least as large as the
+/// chunk size.
+///
+/// @param[in] chunk The chunk size
+/// @param[in] minimum The minimum size (or maybe the minimum number of chunks?)
+/// @return The aligned size
+///
+inline unsigned int ATTR_DLL_LOCAL GetChunkSize(unsigned int chunk, unsigned int minimum)
+{
+ if (chunk)
+ return chunk * ((minimum + chunk - 1) / chunk);
+ else
+ return minimum;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Checks the given path contains a known internet protocol.
+///
+/// About following protocols are the path checked:
+/// | Protocol | Return true condition | Protocol | Return true condition
+/// |----------|-----------------------|----------|-----------------------
+/// | **dav** | strictCheck = true | **rtmps** | always
+/// | **davs** | strictCheck = true | **rtmpt** | always
+/// | **ftp** | strictCheck = true | **rtmpte** | always
+/// | **ftps** | strictCheck = true | **rtp** | always
+/// | **http** | always | **rtsp** | always
+/// | **https**| always | **sdp** | always
+/// | **mms** | always | **sftp** | strictCheck = true
+/// | **mmsh** | always | **stack** | always
+/// | **mmst** | always | **tcp** | always
+/// | **rtmp** | always | **udp** | always
+/// | **rtmpe**| always | | |
+///
+/// @param[in] path To checked path/URL
+/// @param[in] strictCheck [opt] If True the set of protocols used will be
+/// extended to include ftp, ftps, dav, davs and sftp.
+/// @return True if path is to a internet stream, false otherwise
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// // Check should return false
+/// fprintf(stderr, "File name 1 is internet stream '%s' (should no)\n",
+/// kodi::vfs::IsInternetStream("D:/my-file.mkv") ? "yes" : "no");
+///
+/// // Check should return true
+/// fprintf(stderr, "File name 2 is internet stream '%s' (should yes)\n",
+/// kodi::vfs::IsInternetStream("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4") ? "yes" : "no");
+///
+/// // Check should return false
+/// fprintf(stderr, "File name 1 is internet stream '%s' (should no)\n",
+/// kodi::vfs::IsInternetStream("ftp://do-somewhere.com/the-file.mkv") ? "yes" : "no", false);
+///
+/// // Check should return true
+/// fprintf(stderr, "File name 1 is internet stream '%s' (should yes)\n",
+/// kodi::vfs::IsInternetStream("ftp://do-somewhere.com/the-file.mkv") ? "yes" : "no", true);
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL IsInternetStream(const std::string& path, bool strictCheck = false)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->is_internet_stream(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str(), strictCheck);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Checks whether the specified path refers to a local network.
+///
+/// In difference to @ref IsHostOnLAN() include this more deeper checks where
+/// also handle Kodi's special protocol and stacks.
+///
+/// @param[in] path To checked path
+/// @return True if path is on LAN, false otherwise
+///
+/// @note Check includes @ref IsHostOnLAN() too.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// // Check should return true
+/// bool lan = kodi::vfs::IsOnLAN("smb://path/to/file");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL IsOnLAN(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->is_on_lan(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Checks specified path for external network.
+///
+/// @param[in] path To checked path
+/// @return True if path is remote, false otherwise
+///
+/// @note This does not apply to the local network.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// // Check should return true
+/// bool remote = kodi::vfs::IsRemote("http://path/to/file");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL IsRemote(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->is_remote(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Checks whether the given path refers to the own system.
+///
+/// @param[in] path To checked path
+/// @return True if path is local, false otherwise
+///
+inline bool ATTR_DLL_LOCAL IsLocal(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->is_local(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Checks specified path is a regular URL, e.g. "someprotocol://path/to/file"
+///
+/// @return True if file item is URL, false otherwise
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+///
+/// bool isURL;
+/// // Check should return true
+/// isURL = kodi::vfs::IsURL("someprotocol://path/to/file");
+///
+/// // Check should return false
+/// isURL = kodi::vfs::IsURL("/path/to/file");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL IsURL(const std::string& path)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->is_url(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str());
+}
+//--------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief To get HTTP header information.
+///
+/// @param[in] url URL source of the data
+/// @param[out] header The @ref cpp_kodi_vfs_Defs_HttpHeader
+/// @return true if successfully done, otherwise false
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_vfs_Defs_HttpHeader_Help
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// kodi::vfs::HttpHeader header;
+/// bool ret = kodi::vfs::GetHttpHeader(url, header);
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetHttpHeader(const std::string& url, HttpHeader& header)
+{
+ using namespace ::kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->get_http_header(
+ CPrivateBase::m_interface->toKodi->kodiBase, url.c_str(), &header.m_handle);
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Get file mime type.
+///
+/// @param[in] url URL source of the data
+/// @param[out] mimeType the mime type of the URL
+/// @param[in] useragent to be used when retrieving the MimeType [opt]
+/// @return true if successfully done, otherwise false
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string mimeType;.
+/// if (kodi::vfs::GetMimeType(url, mimeType))
+/// fprintf(stderr, "The mime type is '%s'\n", mimeType.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetMimeType(const std::string& url,
+ std::string& mimeType,
+ const std::string& useragent = "")
+{
+ using namespace ::kodi::addon;
+
+ char* cMimeType = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_filesystem->get_mime_type(
+ CPrivateBase::m_interface->toKodi->kodiBase, url.c_str(), &cMimeType, useragent.c_str());
+ if (cMimeType != nullptr)
+ {
+ mimeType = cMimeType;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ cMimeType);
+ }
+ return ret;
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Get file content-type.
+///
+/// @param[in] url URL source of the data
+/// @param[out] content The returned type
+/// @param[in] useragent to be used when retrieving the MimeType [opt]
+/// @return true if successfully done, otherwise false
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string content;.
+/// if (kodi::vfs::GetContentType(url, content))
+/// fprintf(stderr, "The content type is '%s'\n", content.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetContentType(const std::string& url,
+ std::string& content,
+ const std::string& useragent = "")
+{
+ using namespace ::kodi::addon;
+
+ char* cContent = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_filesystem->get_content_type(
+ CPrivateBase::m_interface->toKodi->kodiBase, url.c_str(), &cContent, useragent.c_str());
+ if (cContent != nullptr)
+ {
+ content = cContent;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ cContent);
+ }
+ return ret;
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_vfs_General
+/// @brief Get cookies stored by CURL in RFC 2109 format.
+///
+/// @param[in] url URL source of the data
+/// @param[out] cookies The text list of available cookies
+/// @return true if successfully done, otherwise false
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+/// ...
+/// std::string url = "";
+/// std::string cookies;
+/// bool ret = kodi::vfs::GetCookies(url, cookies);
+/// fprintf(stderr, "Cookies from URL '%s' are '%s' (return was %s)\n",
+/// url.c_str(), cookies.c_str(), ret ? "true" : "false");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetCookies(const std::string& url, std::string& cookies)
+{
+ using namespace ::kodi::addon;
+
+ char* cCookies = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_filesystem->get_cookies(
+ CPrivateBase::m_interface->toKodi->kodiBase, url.c_str(), &cCookies);
+ if (cCookies != nullptr)
+ {
+ cookies = cCookies;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ cCookies);
+ }
+ return ret;
+}
+//----------------------------------------------------------------------------
+
+//}}}
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" CFile class
+//{{{
+
+//==============================================================================
+/// @defgroup cpp_kodi_vfs_CFile 4. class CFile
+/// @ingroup cpp_kodi_vfs
+///
+/// @brief **Creatable class for virtual file server control**\n
+/// To perform file read/write with Kodi's filesystem parts.
+///
+/// CFile is the class used for handling Files in Kodi. This class can be used
+/// for creating, reading, writing and modifying files. It directly provides unbuffered, binary disk input/output services
+///
+/// It has the header @ref Filesystem.h "#include <kodi/Filesystem.h>" be included
+/// to enjoy it.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Filesystem.h>
+///
+/// ...
+///
+/// /* Create the needed file handle class */
+/// kodi::vfs::CFile myFile();
+///
+/// /* In this example we use the user path for the add-on */
+/// std::string file = kodi::GetUserPath() + "/myFile.txt";
+///
+/// /* Now create and open the file or overwrite if present */
+/// myFile.OpenFileForWrite(file, true);
+///
+/// const char* str = "I love Kodi!";
+///
+/// /* write string */
+/// myFile.Write(str, sizeof(str));
+///
+/// /* On this way the Close() is not needed to call, becomes done from destructor */
+///
+/// ~~~~~~~~~~~~~
+///
+///@{
+class ATTR_DLL_LOCAL CFile
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Construct a new, unopened file.
+ ///
+ CFile() = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief <b>`Close()`</b> is called from the destructor, so explicitly
+ /// closing the file isn't required.
+ ///
+ virtual ~CFile() { Close(); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Open the file with filename via Kodi's @ref cpp_kodi_vfs_CFile
+ /// "CFile". Needs to be closed by calling Close() when done.
+ ///
+ /// @param[in] filename The filename to open.
+ /// @param[in] flags [opt] The flags to pass, see @ref OpenFileFlags
+ /// @return True on success or false on failure
+ ///
+ bool OpenFile(const std::string& filename, unsigned int flags = 0)
+ {
+ using namespace kodi::addon;
+
+ Close();
+ m_file = CPrivateBase::m_interface->toKodi->kodi_filesystem->open_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str(), flags);
+ return m_file != nullptr;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Open the file with filename via Kodi's @ref cpp_kodi_vfs_CFile
+ /// "CFile" in write mode. Needs to be closed by calling Close() when
+ /// done.
+ ///
+ /// @note Related folders becomes created if not present.
+ ///
+ /// @param[in] filename The filename to open.
+ /// @param[in] overwrite True to overwrite, false otherwise.
+ /// @return True on success or false on failure
+ ///
+ bool OpenFileForWrite(const std::string& filename, bool overwrite = false)
+ {
+ using namespace kodi::addon;
+
+ Close();
+
+ // Try to open the file. If it fails, check if we need to create the directory first
+ // This way we avoid checking if the directory exists every time
+ m_file = CPrivateBase::m_interface->toKodi->kodi_filesystem->open_file_for_write(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str(), overwrite);
+ if (!m_file)
+ {
+ std::string cacheDirectory = kodi::vfs::GetDirectoryName(filename);
+ if (CPrivateBase::m_interface->toKodi->kodi_filesystem->directory_exists(
+ CPrivateBase::m_interface->toKodi->kodiBase, cacheDirectory.c_str()) ||
+ CPrivateBase::m_interface->toKodi->kodi_filesystem->create_directory(
+ CPrivateBase::m_interface->toKodi->kodiBase, cacheDirectory.c_str()))
+ m_file = CPrivateBase::m_interface->toKodi->kodi_filesystem->open_file_for_write(
+ CPrivateBase::m_interface->toKodi->kodiBase, filename.c_str(), overwrite);
+ }
+ return m_file != nullptr;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Check file is opened.
+ ///
+ /// @return True on open or false on closed or failure
+ ///
+ bool IsOpen() const { return m_file != nullptr; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Close an open file.
+ ///
+ void Close()
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return;
+ CPrivateBase::m_interface->toKodi->kodi_filesystem->close_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ m_file = nullptr;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Create a Curl representation
+ ///
+ /// @param[in] url The URL of the Type.
+ /// @return True on success or false on failure
+ ///
+ bool CURLCreate(const std::string& url)
+ {
+ using namespace kodi::addon;
+
+ m_file = CPrivateBase::m_interface->toKodi->kodi_filesystem->curl_create(
+ CPrivateBase::m_interface->toKodi->kodiBase, url.c_str());
+ return m_file != nullptr;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Add options to the curl file created with CURLCreate.
+ ///
+ /// @param[in] type Option type to set, see @ref CURLOptiontype
+ /// @param[in] name Name of the option
+ /// @param[in] value Value of the option
+ /// @return True on success or false on failure
+ ///
+ bool CURLAddOption(CURLOptiontype type, const std::string& name, const std::string& value)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ {
+ kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before!");
+ return false;
+ }
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->curl_add_option(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, type, name.c_str(), value.c_str());
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Open the curl file created with CURLCreate.
+ ///
+ /// @param[in] flags [opt] The flags to pass, see @ref OpenFileFlags
+ /// @return True on success or false on failure
+ ///
+ bool CURLOpen(unsigned int flags = 0)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ {
+ kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before!");
+ return false;
+ }
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->curl_open(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, flags);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Read from an open file.
+ ///
+ /// @param[in] ptr The buffer to store the data in.
+ /// @param[in] size The size of the buffer.
+ /// @return number of successfully read bytes if any bytes were read and
+ /// stored in buffer, zero if no bytes are available to read (end of
+ /// file was reached) or undetectable error occur, -1 in case of any
+ /// explicit error
+ ///
+ ssize_t Read(void* ptr, size_t size)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return -1;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->read_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, ptr, size);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Read a string from an open file.
+ ///
+ /// @param[out] line The buffer to store the data in.
+ /// @return True when a line was read, false otherwise.
+ ///
+ bool ReadLine(std::string& line)
+ {
+ using namespace kodi::addon;
+
+ line.clear();
+ if (!m_file)
+ return false;
+ // Read 1024 chars into buffer. If file position advanced that many
+ // chars, we didn't hit a newline. Otherwise, we read a newline
+ // or we reached the end of the file.
+ //
+ // The strncpy idiom is used here (C++ allows a simpler implementation):
+ //
+ // char buffer[BUFFER_SIZE];
+ // strncpy(buffer, sourceString, BUFFER_SIZE - 1);
+ // buffer[BUFFER_SIZE - 1] = '\0';
+ //
+ char buffer[1025]{};
+ if (CPrivateBase::m_interface->toKodi->kodi_filesystem->read_file_string(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, buffer, sizeof(buffer) - 1))
+ {
+ line = buffer;
+ return !line.empty();
+ }
+ return false;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Write to a file opened in write mode.
+ ///
+ /// @param[in] ptr Pointer to the data to write, converted to a <b>`const void*`</b>.
+ /// @param[in] size Size of the data to write.
+ /// @return number of successfully written bytes if any bytes were written,
+ /// zero if no bytes were written and no detectable error occur,-1
+ /// in case of any explicit error
+ ///
+ ssize_t Write(const void* ptr, size_t size)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return -1;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->write_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, ptr, size);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Flush buffered data.
+ ///
+ /// If the given stream was open for writing (or if it was open for updating
+ /// and the last i/o operation was an output operation) any unwritten data
+ /// in its output buffer is written to the file.
+ ///
+ /// The stream remains open after this call.
+ ///
+ /// When a file is closed, either because of a call to close or because the
+ /// class is destructed, all the buffers associated with it are
+ /// automatically flushed.
+ ///
+ void Flush()
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return;
+ CPrivateBase::m_interface->toKodi->kodi_filesystem->flush_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Set the file's current position.
+ ///
+ /// The whence argument is optional and defaults to SEEK_SET (0)
+ ///
+ /// @param[in] position the position that you want to seek to
+ /// @param[in] whence [optional] offset relative to You can set the value of
+ /// whence to one of three things:
+ /// | Value | int | Description |
+ /// |:--------:|:---:|:----------------------------------------------------|
+ /// | SEEK_SET | 0 | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
+ /// | SEEK_CUR | 1 | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
+ /// | SEEK_END | 2 | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
+ ///
+ /// @return Returns the resulting offset location as measured in bytes from
+ /// the beginning of the file. On error, the value -1 is returned.
+ ///
+ int64_t Seek(int64_t position, int whence = SEEK_SET)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return -1;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->seek_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, position, whence);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Truncate a file to the requested size.
+ ///
+ /// @param[in] size The new max size.
+ /// @return New size? On error, the value -1 is returned.
+ ///
+ int Truncate(int64_t size)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return -1;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->truncate_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, size);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief The current offset in an open file.
+ ///
+ /// @return The requested offset. On error, the value -1 is returned.
+ ///
+ int64_t GetPosition() const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return -1;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->get_file_position(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Get the file size of an open file.
+ ///
+ /// @return The requested size. On error, the value -1 is returned.
+ ///
+ int64_t GetLength() const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return -1;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->get_file_length(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Checks the file access is on end position.
+ ///
+ /// @return If you've reached the end of the file, AtEnd() returns true.
+ ///
+ bool AtEnd() const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return true;
+ int64_t length = CPrivateBase::m_interface->toKodi->kodi_filesystem->get_file_length(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ int64_t position = CPrivateBase::m_interface->toKodi->kodi_filesystem->get_file_position(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ return position >= length;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Get the chunk size for an open file.
+ ///
+ /// @return The requested size. On error, the value -1 is returned.
+ ///
+ int GetChunkSize() const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return -1;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->get_file_chunk_size(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief To check seek possible on current stream by file.
+ ///
+ /// @return true if seek possible, false if not
+ ///
+ bool IoControlGetSeekPossible() const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return false;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->io_control_get_seek_possible(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief To check a running stream on file for state of his cache.
+ ///
+ /// @param[in] status Information about current cache status
+ /// @return true if successfully done, false otherwise
+ ///
+ ///
+ /// @copydetails cpp_kodi_vfs_Defs_CacheStatus_Help
+ ///
+ bool IoControlGetCacheStatus(CacheStatus& status) const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return false;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->io_control_get_cache_status(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, status);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Unsigned int with speed limit for caching in bytes per second.
+ ///
+ /// @param[in] rate Cache rate size to use
+ /// @return true if successfully done, false otherwise
+ ///
+ bool IoControlSetCacheRate(uint32_t rate)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return false;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->io_control_set_cache_rate(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, rate);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Enable/disable retry within the protocol handler (if supported).
+ ///
+ /// @param[in] retry To set the retry, true for use, false for not
+ /// @return true if successfully done, false otherwise
+ ///
+ bool IoControlSetRetry(bool retry)
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return false;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->io_control_set_retry(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, retry);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @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 GetPropertyValue(FilePropertyTypes type, const std::string& name) const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ {
+ kodi::Log(ADDON_LOG_ERROR,
+ "kodi::vfs::CURLCreate(...) needed to call before GetPropertyValue!");
+ return "";
+ }
+ std::vector<std::string> values = GetPropertyValues(type, name);
+ if (values.empty())
+ {
+ return "";
+ }
+ return values[0];
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Retrieve file property values.
+ ///
+ /// @param[in] type The type of the file property values to retrieve the value for
+ /// @param[in] name The name of the named property (e.g. Header)
+ /// @return values of requested property, empty vector on failure / non-existance
+ ///
+ const std::vector<std::string> GetPropertyValues(FilePropertyTypes type,
+ const std::string& name) const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ {
+ kodi::Log(ADDON_LOG_ERROR,
+ "kodi::vfs::CURLCreate(...) needed to call before GetPropertyValues!");
+ return std::vector<std::string>();
+ }
+ int numValues = 0;
+ char** res(CPrivateBase::m_interface->toKodi->kodi_filesystem->get_property_values(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file, type, name.c_str(), &numValues));
+ if (res)
+ {
+ std::vector<std::string> vecReturn;
+ vecReturn.reserve(numValues);
+ for (int i = 0; i < numValues; ++i)
+ {
+ vecReturn.emplace_back(res[i]);
+ }
+ CPrivateBase::m_interface->toKodi->free_string_array(
+ CPrivateBase::m_interface->toKodi->kodiBase, res, numValues);
+ return vecReturn;
+ }
+ return std::vector<std::string>();
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_vfs_CFile
+ /// @brief Get the current download speed of file if loaded from web.
+ ///
+ /// @return The current download speed.
+ ///
+ double GetFileDownloadSpeed() const
+ {
+ using namespace kodi::addon;
+
+ if (!m_file)
+ return 0.0;
+ return CPrivateBase::m_interface->toKodi->kodi_filesystem->get_file_download_speed(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_file);
+ }
+ //--------------------------------------------------------------------------
+
+private:
+ void* m_file = nullptr;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//}}}
+
+} /* namespace vfs */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/General.h b/xbmc/addons/kodi-dev-kit/include/kodi/General.h
new file mode 100644
index 0000000..71678c2
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/General.h
@@ -0,0 +1,688 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "AddonBase.h"
+#include "c-api/general.h"
+#include "tools/StringUtils.h"
+
+#ifdef __cplusplus
+
+//==============================================================================
+/// \ingroup cpp_kodi_Defs
+/// @brief For kodi::Version used structure
+///
+typedef struct kodi_version_t
+{
+ /// Application name, normally 'Kodi'
+ std::string compile_name;
+ /// Major code version of Kodi
+ int major;
+ /// Minor code version of Kodi
+ int minor;
+ /// The Revision contains a id and the build date, e.g. 20170706-c6b22fe217-dirty
+ std::string revision;
+ /// The version candidate e.g. alpha, beta or release
+ std::string tag;
+ /// The revision of tag before
+ std::string tag_revision;
+} kodi_version_t;
+//------------------------------------------------------------------------------
+
+namespace kodi
+{
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Translate a string with an unknown encoding to UTF8.
+///
+/// @param[in] stringSrc The string to translate.
+/// @param[out] utf8StringDst The translated string.
+/// @param[in] failOnBadChar [opt] returns failed if bad character is inside <em>(default is <b><c>false</c></b>)</em>
+/// @return true if OK
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string ret;
+/// if (!kodi::UnknownToUTF8("test string", ret, true))
+/// fprintf(stderr, "Translation to UTF8 failed!\n");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL UnknownToUTF8(const std::string& stringSrc,
+ std::string& utf8StringDst,
+ bool failOnBadChar = false)
+{
+ using namespace kodi::addon;
+
+ bool ret = false;
+ char* retString = CPrivateBase::m_interface->toKodi->kodi->unknown_to_utf8(
+ CPrivateBase::m_interface->toKodi->kodiBase, stringSrc.c_str(), &ret, failOnBadChar);
+ if (retString != nullptr)
+ {
+ if (ret)
+ utf8StringDst = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Returns the active language as a string.
+///
+/// @param[in] format Used format of the returned language string
+/// | enum code: | Description: |
+/// |----------------------:|------------------------------------------------------------|
+/// | LANG_FMT_ENGLISH_NAME | full language name in English (Default) |
+/// | LANG_FMT_ISO_639_1 | two letter code as defined in ISO 639-1 |
+/// | LANG_FMT_ISO_639_2 | three letter code as defined in ISO 639-2/T or ISO 639-2/B |
+/// @param[in] region [opt] append the region delimited by "-" of the language (setting) to the returned language string <em>(default is <b><c>false</c></b>)</em>
+/// @return active language
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string language = kodi::GetLanguage(LANG_FMT_ISO_639_1, false);
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetLanguage(LangFormats format = LANG_FMT_ENGLISH_NAME,
+ bool region = false)
+{
+ using namespace kodi::addon;
+
+ std::string language;
+ char* retString = CPrivateBase::m_interface->toKodi->kodi->get_language(
+ CPrivateBase::m_interface->toKodi->kodiBase, format, region);
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ language = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return language;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Writes the C string pointed by format in the GUI. If format includes
+/// format specifiers (subsequences beginning with %), the additional arguments
+/// following format are formatted and inserted in the resulting string replacing
+/// their respective specifiers.
+///
+/// After the format parameter, the function expects at least as many additional
+/// arguments as specified by format.
+///
+/// @param[in] type The message type.
+/// | enum code: | Description: |
+/// |---------------:|-----------------------------------|
+/// | QUEUE_INFO | Show info notification message |
+/// | QUEUE_WARNING | Show warning notification message |
+/// | QUEUE_ERROR | Show error notification message |
+/// @param[in] format The format of the message to pass to display in Kodi.
+/// C string that contains the text to be written to the stream.
+/// It can optionally contain embedded format specifiers that are
+/// replaced by the values specified in subsequent additional
+/// arguments and formatted as requested.
+/// | specifier | Output | Example
+/// |------------|----------------------------------------------------|------------
+/// | d or i | Signed decimal integer | 392
+/// | u | Unsigned decimal integer | 7235
+/// | o | Unsigned octal | 610
+/// | x | Unsigned hexadecimal integer | 7fa
+/// | X | Unsigned hexadecimal integer (uppercase) | 7FA
+/// | f | Decimal floating point, lowercase | 392.65
+/// | F | Decimal floating point, uppercase | 392.65
+/// | e | Scientific notation (mantissa/exponent), lowercase | 3.9265e+2
+/// | E | Scientific notation (mantissa/exponent), uppercase | 3.9265E+2
+/// | g | Use the shortest representation: %e or %f | 392.65
+/// | G | Use the shortest representation: %E or %F | 392.65
+/// | a | Hexadecimal floating point, lowercase | -0xc.90fep-2
+/// | A | Hexadecimal floating point, uppercase | -0XC.90FEP-2
+/// | c | Character | a
+/// | s | String of characters | sample
+/// | p | Pointer address | b8000000
+/// | % | A % followed by another % character will write a single % to the stream. | %
+///
+/// The length sub-specifier modifies the length of the data type. This is a chart
+/// showing the types used to interpret the corresponding arguments with and without
+/// length specifier (if a different type is used, the proper type promotion or
+/// conversion is performed, if allowed):
+/// | length| d i | u o x X | f F e E g G a A | c | s | p | n |
+/// |-------|---------------|-----------------------|-----------------|-------|---------|---------|-----------------|
+/// | (none)| int | unsigned int | double | int | char* | void* | int* |
+/// | hh | signed char | unsigned char | | | | | signed char* |
+/// | h | short int | unsigned short int | | | | | short int* |
+/// | l | long int | unsigned long int | | wint_t| wchar_t*| | long int* |
+/// | ll | long long int | unsigned long long int| | | | | long long int* |
+/// | j | intmax_t | uintmax_t | | | | | intmax_t* |
+/// | z | size_t | size_t | | | | | size_t* |
+/// | t | ptrdiff_t | ptrdiff_t | | | | | ptrdiff_t* |
+/// | L | | | long double | | | | |
+/// <b>Note:</b> that the c specifier takes an int (or wint_t) as argument, but performs the proper conversion to a char value
+/// (or a wchar_t) before formatting it for output.
+/// @param[in] ... (additional arguments) Depending on the format string, the function
+/// may expect a sequence of additional arguments, each containing a value
+/// to be used to replace a format specifier in the format string (or a pointer
+/// to a storage location, for n).
+/// There should be at least as many of these arguments as the number of values specified
+/// in the format specifiers. Additional arguments are ignored by the function.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// kodi::QueueFormattedNotification(QUEUE_WARNING, "I'm want to inform you, here with a test call to show '%s'", "this");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL QueueFormattedNotification(QueueMsg type, const char* format, ...)
+{
+ using namespace kodi::addon;
+
+ va_list args;
+ va_start(args, format);
+ const std::string str = kodi::tools::StringUtils::FormatV(format, args);
+ va_end(args);
+ CPrivateBase::m_interface->toKodi->kodi->queue_notification(
+ CPrivateBase::m_interface->toKodi->kodiBase, type, "", str.c_str(), "", 5000, false, 1000);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Queue a notification in the GUI.
+///
+/// @param[in] type The message type.
+/// | enum code: | Description:
+/// |----------------------:|-----------------------------------
+/// | QUEUE_INFO | Show info notification message
+/// | QUEUE_WARNING | Show warning notification message
+/// | QUEUE_ERROR | Show error notification message
+/// | QUEUE_OWN_STYLE | If used can be with imageFile the wanted image set or if leaved empty shown as info, also are the other optional values available then
+/// @param[in] header Header Name (if leaved empty becomes addon name used)
+/// @param[in] message Message to display on Kodi
+/// @param[in] imageFile [opt] The image file to show on message (to use must be type set to QUEUE_OWN_STYLE)
+/// @param[in] displayTime [opt] The time how long message is displayed <b>(default 5 sec)</b> (to use must be type set to QUEUE_OWN_STYLE)
+/// @param[in] withSound [opt] if true also warning sound becomes played <b>(default with sound)</b> (to use must be type set to QUEUE_OWN_STYLE)
+/// @param[in] messageTime [opt] how many milli seconds start show of notification <b>(default 1 sec)</b> (to use must be type set to QUEUE_OWN_STYLE)
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// kodi::QueueNotification(QUEUE_OWN_STYLE, "I'm want to inform you", "Here with a test call", "", 3000, false, 1000);
+/// ...
+/// ~~~~~~~~~~~~~
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// kodi::QueueNotification(QUEUE_WARNING, "I'm want to inform you", "Here with a test call");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// kodi::QueueNotification(QUEUE_OWN_STYLE, "", "Here with a test call", "./myImage.png");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL QueueNotification(QueueMsg type,
+ const std::string& header,
+ const std::string& message,
+ const std::string& imageFile = "",
+ unsigned int displayTime = 5000,
+ bool withSound = true,
+ unsigned int messageTime = 1000)
+{
+ using namespace kodi::addon;
+
+ CPrivateBase::m_interface->toKodi->kodi->queue_notification(
+ CPrivateBase::m_interface->toKodi->kodiBase, type, header.c_str(), message.c_str(),
+ imageFile.c_str(), displayTime, withSound, messageTime);
+}
+//------------------------------------------------------------------------------
+
+//============================================================================
+/// \ingroup cpp_kodi
+/// @brief Get the MD5 digest of the given text
+///
+/// @param[in] text text to compute the MD5 for
+/// @return Returned MD5 digest
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string md5 = kodi::GetMD5("Make me as md5");
+/// fprintf(stderr, "My md5 digest is: '%s'\n", md5.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetMD5(const std::string& text)
+{
+ using namespace kodi::addon;
+
+ char* md5ret = static_cast<char*>(malloc(40 * sizeof(char))); // md5 size normally 32 bytes
+ CPrivateBase::m_interface->toKodi->kodi->get_md5(CPrivateBase::m_interface->toKodi->kodiBase,
+ text.c_str(), md5ret);
+ std::string md5 = md5ret;
+ free(md5ret);
+ return md5;
+}
+//----------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Returns your regions setting as a string for the specified id
+///
+/// @param[in] id id of setting to return
+/// | | Choices are | |
+/// |:------------:|:------------:|:------------:|
+/// | dateshort | time | tempunit |
+/// | datelong | meridiem | speedunit |
+///
+/// @return settings string
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string timeFormat = kodi::GetRegion("time");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetRegion(const std::string& id)
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+
+ std::string strReturn;
+ char* strMsg = toKodi->kodi->get_region(toKodi->kodiBase, id.c_str());
+ if (strMsg != nullptr)
+ {
+ if (std::strlen(strMsg))
+ strReturn = strMsg;
+ toKodi->free_string(toKodi->kodiBase, strMsg);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Returns the amount of free memory in MByte (or as bytes) as an long
+/// integer
+///
+/// @param[out] free free memory
+/// @param[out] total total memory
+/// @param[in] asBytes [opt] if set to true becomes returned as bytes, otherwise
+/// as mega bytes
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// long freeMem;
+/// long totalMem;
+/// kodi::GetFreeMem(freeMem, totalMem);
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL GetFreeMem(long& free, long& total, bool asBytes = false)
+{
+ using namespace kodi::addon;
+
+ free = -1;
+ total = -1;
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+ toKodi->kodi->get_free_mem(toKodi->kodiBase, &free, &total, asBytes);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Returns the elapsed idle time in seconds as an integer
+///
+/// @return idle time
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// int time = kodi::GetGlobalIdleTime();
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline int ATTR_DLL_LOCAL GetGlobalIdleTime()
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+ return toKodi->kodi->get_global_idle_time(toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Get the currently used skin identification name from Kodi
+///
+/// @return The active skin id name as a string
+///
+///
+/// @note This is not the full path like 'special://home/addons/MediaCenter',
+/// but only 'MediaCenter'.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ..
+/// std::string skinid = kodi::GetCurrentSkinId();
+/// ..
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetCurrentSkinId()
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+
+ std::string strReturn;
+ char* strMsg = toKodi->kodi->get_current_skin_id(toKodi->kodiBase);
+ if (strMsg != nullptr)
+ {
+ if (std::strlen(strMsg))
+ strReturn = strMsg;
+ toKodi->free_string(toKodi->kodiBase, strMsg);
+ }
+ return strReturn;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief To check another addon is available and usable inside Kodi.
+///
+/// @param[in] id The wanted addon identification string to check
+/// @param[out] version Version string of addon if **installed** inside Kodi
+/// @param[out] enabled Set to true <b>`true* </b> if addon is enabled
+/// @return Returns <b>`true* </b> if addon is installed
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+///
+/// bool enabled = false;
+/// std::string version;
+/// bool ret = kodi::IsAddonAvailable("inputstream.adaptive", version, enabled);
+/// fprintf(stderr, "Available inputstream.adaptive version '%s' and enabled '%s'\n",
+/// ret ? version.c_str() : "not installed", enabled ? "yes" : "no");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL IsAddonAvailable(const std::string& id,
+ std::string& version,
+ bool& enabled)
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+
+ char* cVersion = nullptr;
+ bool ret = toKodi->kodi->is_addon_avilable(toKodi->kodiBase, id.c_str(), &cVersion, &enabled);
+ if (cVersion)
+ {
+ version = cVersion;
+ toKodi->free_string(toKodi->kodiBase, cVersion);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief Get current Kodi information and versions, returned data from the following
+/// <b><tt>kodi_version_t version; kodi::KodiVersion(version);</tt></b>
+/// is e.g.:
+/// ~~~~~~~~~~~~~{.cpp}
+/// version.compile_name = Kodi
+/// version.major = 18
+/// version.minor = 0
+/// version.revision = 20170706-c6b22fe217-di
+/// version.tag = alpha
+/// version.tag_revision = 1
+/// ~~~~~~~~~~~~~
+///
+/// @param[out] version structure to store data from kodi
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// kodi_version_t version;
+/// kodi::KodiVersion(version);
+/// fprintf(stderr,
+/// "kodi_version_t version;\n"
+/// "kodi::KodiVersion(version);\n"
+/// " - version.compile_name = %s\n"
+/// " - version.major = %i\n"
+/// " - version.minor = %i\n"
+/// " - version.revision = %s\n"
+/// " - version.tag = %s\n"
+/// " - version.tag_revision = %s\n",
+/// version.compile_name.c_str(), version.major, version.minor,
+/// version.revision.c_str(), version.tag.c_str(), version.tag_revision.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL KodiVersion(kodi_version_t& version)
+{
+ using namespace kodi::addon;
+
+ char* compile_name = nullptr;
+ char* revision = nullptr;
+ char* tag = nullptr;
+ char* tag_revision = nullptr;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+ toKodi->kodi->kodi_version(toKodi->kodiBase, &compile_name, &version.major, &version.minor,
+ &revision, &tag, &tag_revision);
+ if (compile_name != nullptr)
+ {
+ version.compile_name = compile_name;
+ toKodi->free_string(toKodi->kodiBase, compile_name);
+ }
+ if (revision != nullptr)
+ {
+ version.revision = revision;
+ toKodi->free_string(toKodi->kodiBase, revision);
+ }
+ if (tag != nullptr)
+ {
+ version.tag = tag;
+ toKodi->free_string(toKodi->kodiBase, tag);
+ }
+ if (tag_revision != nullptr)
+ {
+ version.tag_revision = tag_revision;
+ toKodi->free_string(toKodi->kodiBase, tag_revision);
+ }
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief To get keyboard layout characters
+///
+/// This is used to get the keyboard layout currently used from Kodi by the
+/// there set language.
+///
+/// @param[in] modifierKey the key to define the needed layout (uppercase, symbols...)
+/// @param[out] layout_name name of used layout
+/// @param[out] layout list of selected keyboard layout
+/// @return true if request successed
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string layout_name;
+/// std::vector<std::vector<std::string>> layout;
+/// kodi::GetKeyboardLayout(STD_KB_MODIFIER_KEY_SHIFT | STD_KB_MODIFIER_KEY_SYMBOL, layout_name, layout);
+/// fprintf(stderr, "Layout: '%s'\n", layout_name.c_str());
+/// for (unsigned int row = 0; row < STD_KB_BUTTONS_MAX_ROWS; row++)
+/// {
+/// for (unsigned int column = 0; column < STD_KB_BUTTONS_PER_ROW; column++)
+/// {
+/// fprintf(stderr, " - Row: '%02i'; Column: '%02i'; Text: '%s'\n", row, column, layout[row][column].c_str());
+/// }
+/// }
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL GetKeyboardLayout(int modifierKey,
+ std::string& layout_name,
+ std::vector<std::vector<std::string>>& layout)
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+ AddonKeyboardKeyTable c_layout;
+ char* c_layout_name = nullptr;
+ bool ret =
+ toKodi->kodi->get_keyboard_layout(toKodi->kodiBase, &c_layout_name, modifierKey, &c_layout);
+ if (ret)
+ {
+ if (c_layout_name)
+ {
+ layout_name = c_layout_name;
+ toKodi->free_string(toKodi->kodiBase, c_layout_name);
+ }
+
+ layout.resize(STD_KB_BUTTONS_MAX_ROWS);
+ for (unsigned int row = 0; row < STD_KB_BUTTONS_MAX_ROWS; row++)
+ {
+ layout[row].resize(STD_KB_BUTTONS_PER_ROW);
+ for (unsigned int column = 0; column < STD_KB_BUTTONS_PER_ROW; column++)
+ {
+ char* button = c_layout.keys[row][column];
+ if (button)
+ {
+ layout[row][column] = button;
+ toKodi->free_string(toKodi->kodiBase, button);
+ }
+ }
+ }
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// \ingroup cpp_kodi
+/// @brief To change keyboard layout characters
+///
+/// This is used to change the keyboard layout currently used from Kodi
+///
+/// @param[out] layout_name new name of used layout (input string not used!)
+/// @return true if request successed
+///
+/// @note @ref GetKeyboardLayout must be called afterwards.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// ...
+/// std::string layout_name;
+/// kodi::ChangeKeyboardLayout(layout_name);
+///
+/// std::vector<std::vector<std::string>> layout;
+/// kodi::GetKeyboardLayout(STD_KB_MODIFIER_KEY_SHIFT | STD_KB_MODIFIER_KEY_SYMBOL, layout_name, layout);
+/// fprintf(stderr, "Layout: '%s'\n", layout_name.c_str());
+/// for (unsigned int row = 0; row < STD_KB_BUTTONS_MAX_ROWS; row++)
+/// {
+/// for (unsigned int column = 0; column < STD_KB_BUTTONS_PER_ROW; column++)
+/// {
+/// fprintf(stderr, " - Row: '%02i'; Column: '%02i'; Text: '%s'\n", row, column, layout[row][column].c_str());
+/// }
+/// }
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ChangeKeyboardLayout(std::string& layout_name)
+{
+ using namespace kodi::addon;
+
+ AddonToKodiFuncTable_Addon* toKodi = CPrivateBase::m_interface->toKodi;
+ char* c_layout_name = nullptr;
+ bool ret = toKodi->kodi->change_keyboard_layout(toKodi->kodiBase, &c_layout_name);
+ if (c_layout_name)
+ {
+ layout_name = c_layout_name;
+ toKodi->free_string(toKodi->kodiBase, c_layout_name);
+ }
+
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/Network.h b/xbmc/addons/kodi-dev-kit/include/kodi/Network.h
new file mode 100644
index 0000000..e6ff2c9
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/Network.h
@@ -0,0 +1,287 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "AddonBase.h"
+#include "c-api/network.h"
+
+#ifdef __cplusplus
+
+//==============================================================================
+/// @defgroup cpp_kodi_network Interface - kodi::network
+/// @ingroup cpp
+/// @brief **Network functions**\n
+/// The network module offers functions that allow you to control it.
+///
+/// It has the header @ref Network.h "#include <kodi/Network.h>" be included
+/// to enjoy it.
+///
+//------------------------------------------------------------------------------
+
+namespace kodi
+{
+namespace network
+{
+
+//============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief Send WakeOnLan magic packet.
+///
+/// @param[in] mac Network address of the host to wake.
+/// @return True if the magic packet was successfully sent, false otherwise.
+///
+inline bool ATTR_DLL_LOCAL WakeOnLan(const std::string& mac)
+{
+ using namespace ::kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_network->wake_on_lan(
+ CPrivateBase::m_interface->toKodi->kodiBase, mac.c_str());
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief To the current own ip address as a string.
+///
+/// @return Own system ip.
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Network.h>
+/// ...
+/// std::string ipAddress = kodi::network::GetIPAddress();
+/// fprintf(stderr, "My IP is '%s'\n", ipAddress.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetIPAddress()
+{
+ using namespace ::kodi::addon;
+
+ std::string ip;
+ char* string = CPrivateBase::m_interface->toKodi->kodi_network->get_ip_address(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ if (string != nullptr)
+ {
+ ip = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return ip;
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief Return our hostname.
+///
+/// @return String about hostname, empty in case of error
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Network.h>
+/// ...
+/// std::string hostname = kodi::network::GetHostname();
+/// fprintf(stderr, "My hostname is '%s'\n", hostname.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline std::string ATTR_DLL_LOCAL GetHostname()
+{
+ using namespace ::kodi::addon;
+
+ std::string ip;
+ char* string = CPrivateBase::m_interface->toKodi->kodi_network->get_hostname(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ if (string != nullptr)
+ {
+ ip = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return ip;
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief Returns Kodi's HTTP UserAgent string.
+///
+/// @return HTTP user agent
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.py}
+/// ..
+/// std::string agent = kodi::network::GetUserAgent()
+/// ..
+/// ~~~~~~~~~~~~~
+///
+/// example output:
+/// Kodi/19.0-ALPHA1 (X11; Linux x86_64) Ubuntu/20.04 App_Bitness/64 Version/19.0-ALPHA1-Git:20200522-0076d136d3-dirty
+///
+inline std::string ATTR_DLL_LOCAL GetUserAgent()
+{
+ using namespace ::kodi::addon;
+
+ std::string agent;
+ char* string = CPrivateBase::m_interface->toKodi->kodi_network->get_user_agent(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ if (string != nullptr)
+ {
+ agent = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return agent;
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief Check given name or ip address corresponds to localhost.
+///
+/// @param[in] hostname Hostname to check
+/// @return Return true if given name or ip address corresponds to localhost
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Network.h>
+/// ...
+/// if (kodi::network::IsLocalHost("127.0.0.1"))
+/// fprintf(stderr, "Is localhost\n");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL IsLocalHost(const std::string& hostname)
+{
+ using namespace ::kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_network->is_local_host(
+ CPrivateBase::m_interface->toKodi->kodiBase, hostname.c_str());
+}
+//----------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief Checks whether the specified path refers to a local network.
+///
+/// @param[in] hostname Hostname to check
+/// @param[in] offLineCheck Check if in private range, see https://en.wikipedia.org/wiki/Private_network
+/// @return True if host is on a LAN, false otherwise
+///
+inline bool ATTR_DLL_LOCAL IsHostOnLAN(const std::string& hostname, bool offLineCheck = false)
+{
+ using namespace kodi::addon;
+
+ return CPrivateBase::m_interface->toKodi->kodi_network->is_host_on_lan(
+ CPrivateBase::m_interface->toKodi->kodiBase, hostname.c_str(), offLineCheck);
+}
+//------------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief URL encodes the given string
+///
+/// This function converts the given input string to a URL encoded string and
+/// returns that as a new allocated string. All input characters that are
+/// not a-z, A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped"
+/// version (%NN where NN is a two-digit hexadecimal number).
+///
+/// @param[in] url The code of the message to get.
+/// @return Encoded URL string
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Network.h>
+/// ...
+/// std::string encodedUrl = kodi::network::URLEncode("François");
+/// fprintf(stderr, "Encoded URL is '%s'\n", encodedUrl.c_str());
+/// ...
+/// ~~~~~~~~~~~~~
+/// For example, the string: François ,would be encoded as: Fran%C3%A7ois
+///
+inline std::string ATTR_DLL_LOCAL URLEncode(const std::string& url)
+{
+ using namespace ::kodi::addon;
+
+ std::string retString;
+ char* string = CPrivateBase::m_interface->toKodi->kodi_network->url_encode(
+ CPrivateBase::m_interface->toKodi->kodiBase, url.c_str());
+ if (string != nullptr)
+ {
+ retString = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return retString;
+}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_network
+/// @brief Lookup URL in DNS cache
+///
+/// This test will get DNS record for a domain. The DNS lookup is done directly
+/// against the domain's authoritative name server, so changes to DNS Records
+/// should show up instantly. By default, the DNS lookup tool will return an
+/// IP address if you give it a name (e.g. www.example.com)
+///
+/// @param[in] hostName The code of the message to get.
+/// @param[out] ipAddress Returned address
+/// @return true if successful
+///
+///
+/// ------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/Network.h>
+/// ...
+/// std::string ipAddress;
+/// bool ret = kodi::network::DNSLookup("www.google.com", ipAddress);
+/// fprintf(stderr, "DNSLookup returned for www.google.com the IP '%s', call was %s\n", ipAddress.c_str(), ret ? "ok" : "failed");
+/// ...
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL DNSLookup(const std::string& hostName, std::string& ipAddress)
+{
+ using namespace ::kodi::addon;
+
+ bool ret = false;
+ char* string = CPrivateBase::m_interface->toKodi->kodi_network->dns_lookup(
+ CPrivateBase::m_interface->toKodi->kodiBase, hostName.c_str(), &ret);
+ if (string != nullptr)
+ {
+ ipAddress = string;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ string);
+ }
+ return ret;
+}
+//----------------------------------------------------------------------------
+
+} /* namespace network */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h
new file mode 100644
index 0000000..8569bc3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h
@@ -0,0 +1,728 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../AudioEngine.h"
+#include "../c-api/addon-instance/audiodecoder.h"
+
+#ifdef __cplusplus
+
+#include <cstring>
+#include <stdexcept>
+
+namespace kodi
+{
+namespace addon
+{
+
+class CInstanceAudioDecoder;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_audiodecoder_Defs_AudioDecoderInfoTag class AudioDecoderInfoTag
+/// @ingroup cpp_kodi_addon_audiodecoder_Defs
+/// @brief **Info tag data structure**\n
+/// Representation of available information of processed audio file.
+///
+/// This is used to store all the necessary data of audio stream and to have on
+/// e.g. GUI for information.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_audiodecoder_Defs_AudioDecoderInfoTag_Help
+///
+///@{
+class ATTR_DLL_LOCAL AudioDecoderInfoTag
+{
+public:
+ /*! \cond PRIVATE */
+ AudioDecoderInfoTag() = default;
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_audiodecoder_Defs_AudioDecoderInfoTag_Help Value Help
+ /// @ingroup cpp_kodi_addon_audiodecoder_Defs_AudioDecoderInfoTag
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_audiodecoder_Defs_AudioDecoderInfoTag :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Title** | `std::string` | @ref AudioDecoderInfoTag::SetTitle "SetTitle" | @ref AudioDecoderInfoTag::GetTitle "GetTitle"
+ /// | **Artist** | `std::string` | @ref AudioDecoderInfoTag::SetArtist "SetArtist" | @ref AudioDecoderInfoTag::GetArtist "GetArtist"
+ /// | **Album** | `std::string` | @ref AudioDecoderInfoTag::SetAlbum "SetAlbum" | @ref AudioDecoderInfoTag::GetAlbum "GetAlbum"
+ /// | **Album artist** | `std::string` | @ref AudioDecoderInfoTag::SetAlbumArtist "SetAlbumArtist" | @ref AudioDecoderInfoTag::GetAlbumArtist "GetAlbumArtist"
+ /// | **Media type** | `std::string` | @ref AudioDecoderInfoTag::SetMediaType "SetMediaType" | @ref AudioDecoderInfoTag::GetMediaType "GetMediaType"
+ /// | **Genre** | `std::string` | @ref AudioDecoderInfoTag::SetGenre "SetGenre" | @ref AudioDecoderInfoTag::GetGenre "GetGenre"
+ /// | **Duration** | `int` | @ref AudioDecoderInfoTag::SetDuration "SetDuration" | @ref AudioDecoderInfoTag::GetDuration "GetDuration"
+ /// | **Track number** | `int` | @ref AudioDecoderInfoTag::SetTrack "SetTrack" | @ref AudioDecoderInfoTag::GetTrack "GetTrack"
+ /// | **Disc number** | `int` | @ref AudioDecoderInfoTag::SetDisc "SetDisc" | @ref AudioDecoderInfoTag::GetDisc "GetDisc"
+ /// | **Disc subtitle name** | `std::string` | @ref AudioDecoderInfoTag::SetDiscSubtitle "SetDiscSubtitle" | @ref AudioDecoderInfoTag::GetDiscSubtitle "GetDiscSubtitle"
+ /// | **Disc total amount** | `int` | @ref AudioDecoderInfoTag::SetDiscTotal "SetDiscTotal" | @ref AudioDecoderInfoTag::GetDiscTotal "GetDiscTotal"
+ /// | **Release date** | `std::string` | @ref AudioDecoderInfoTag::SetReleaseDate "SetReleaseDate" | @ref AudioDecoderInfoTag::GetReleaseDate "GetReleaseDate"
+ /// | **Lyrics** | `std::string` | @ref AudioDecoderInfoTag::SetLyrics "SetLyrics" | @ref AudioDecoderInfoTag::GetLyrics "GetLyrics"
+ /// | **Samplerate** | `int` | @ref AudioDecoderInfoTag::SetSamplerate "SetSamplerate" | @ref AudioDecoderInfoTag::GetSamplerate "GetSamplerate"
+ /// | **Channels amount** | `int` | @ref AudioDecoderInfoTag::SetChannels "SetChannels" | @ref AudioDecoderInfoTag::GetChannels "GetChannels"
+ /// | **Bitrate** | `int` | @ref AudioDecoderInfoTag::SetBitrate "SetBitrate" | @ref AudioDecoderInfoTag::GetBitrate "GetBitrate"
+ /// | **Comment text** | `std::string` | @ref AudioDecoderInfoTag::SetComment "SetComment" | @ref AudioDecoderInfoTag::GetComment "GetComment"
+ /// | **Cover art by path** | `std::string` | @ref AudioDecoderInfoTag::SetCoverArtByPath "SetCoverArtByPath" | @ref AudioDecoderInfoTag::GetCoverArtByPath "GetCoverArtByPath"
+ /// | **Cover art by memory** | `std::string` | @ref AudioDecoderInfoTag::SetCoverArtByMem "SetCoverArtByMem" | @ref AudioDecoderInfoTag::GetCoverArtByMem "GetCoverArtByMem"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_audiodecoder_Defs_AudioDecoderInfoTag
+ ///@{
+
+ /// @brief Set the title from music as string on info tag.
+ void SetTitle(const std::string& title) { m_title = title; }
+
+ /// @brief Get title name
+ std::string GetTitle() const { return m_title; }
+
+ /// @brief Set artist name
+ void SetArtist(const std::string& artist) { m_artist = artist; }
+
+ /// @brief Get artist name
+ std::string GetArtist() const { return m_artist; }
+
+ /// @brief Set album name
+ void SetAlbum(const std::string& album) { m_album = album; }
+
+ /// @brief Set album name
+ std::string GetAlbum() const { return m_album; }
+
+ /// @brief Set album artist name
+ void SetAlbumArtist(const std::string& albumArtist) { m_album_artist = albumArtist; }
+
+ /// @brief Get album artist name
+ std::string GetAlbumArtist() const { return m_album_artist; }
+
+ /// @brief Set the media type of the music item.
+ ///
+ /// Available strings about media type for music:
+ /// | String | Description |
+ /// |---------------:|:--------------------------------------------------|
+ /// | artist | If it is defined as an artist
+ /// | album | If it is defined as an album
+ /// | music | If it is defined as an music
+ /// | song | If it is defined as a song
+ ///
+ void SetMediaType(const std::string& mediaType) { m_media_type = mediaType; }
+
+ /// @brief Get the media type of the music item.
+ std::string GetMediaType() const { return m_media_type; }
+
+ /// @brief Set genre name from music as string if present.
+ void SetGenre(const std::string& genre) { m_genre = genre; }
+
+ /// @brief Get genre name from music as string if present.
+ std::string GetGenre() const { return m_genre; }
+
+ /// @brief Set the duration of music as integer from info.
+ void SetDuration(int duration) { m_duration = duration; }
+
+ /// @brief Get the duration of music as integer from info.
+ int GetDuration() const { return m_duration; }
+
+ /// @brief Set track number (if present) from music info as integer.
+ void SetTrack(int track) { m_track = track; }
+
+ /// @brief Get track number (if present).
+ int GetTrack() const { return m_track; }
+
+ /// @brief Set disk number (if present) from music info as integer.
+ void SetDisc(int disc) { m_disc = disc; }
+
+ /// @brief Get disk number (if present)
+ int GetDisc() const { return m_disc; }
+
+ /// @brief Set disk subtitle name (if present) from music info.
+ void SetDiscSubtitle(const std::string& discSubtitle) { m_disc_subtitle = discSubtitle; }
+
+ /// @brief Get disk subtitle name (if present) from music info.
+ std::string GetDiscSubtitle() const { return m_disc_subtitle; }
+
+ /// @brief Set disks amount quantity (if present) from music info as integer.
+ void SetDiscTotal(int discTotal) { m_disc_total = discTotal; }
+
+ /// @brief Get disks amount quantity (if present)
+ int GetDiscTotal() const { return m_disc_total; }
+
+ /// @brief Set release date as string from music info (if present).\n
+ /// [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) date YYYY, YYYY-MM or YYYY-MM-DD
+ void SetReleaseDate(const std::string& releaseDate) { m_release_date = releaseDate; }
+
+ /// @brief Get release date as string from music info (if present).
+ std::string GetReleaseDate() const { return m_release_date; }
+
+ /// @brief Set string from lyrics.
+ void SetLyrics(const std::string& lyrics) { m_lyrics = lyrics; }
+
+ /// @brief Get string from lyrics.
+ std::string GetLyrics() const { return m_lyrics; }
+
+ /// @brief Set related stream samplerate.
+ void SetSamplerate(int samplerate) { m_samplerate = samplerate; }
+
+ /// @brief Get related stream samplerate.
+ int GetSamplerate() const { return m_samplerate; }
+
+ /// @brief Set related stream channels amount.
+ void SetChannels(int channels) { m_channels = channels; }
+
+ /// @brief Get related stream channels amount.
+ int GetChannels() const { return m_channels; }
+
+ /// @brief Set related stream bitrate.
+ void SetBitrate(int bitrate) { m_bitrate = bitrate; }
+
+ /// @brief Get related stream bitrate.
+ int GetBitrate() const { return m_bitrate; }
+
+ /// @brief Set additional information comment (if present).
+ void SetComment(const std::string& comment) { m_comment = comment; }
+
+ /// @brief Get additional information comment (if present).
+ std::string GetComment() const { return m_comment; }
+
+ /// @brief Set cover art image by path.
+ ///
+ /// @param[in] path Image position path
+ ///
+ /// @note Cannot be combined with @ref SetCoverArtByMem and @ref GetCoverArtByMem.
+ void SetCoverArtByPath(const std::string& path) { m_cover_art_path = path; }
+
+ /// @brief Get cover art image path.
+ ///
+ /// @return Image position path
+ ///
+ /// @note Only be available if set before by @ref SetCoverArtByPath.
+ /// Cannot be combined with @ref SetCoverArtByMem and @ref GetCoverArtByMem.
+ ///
+ std::string GetCoverArtByPath() const { return m_cover_art_path; }
+
+ /// @brief Set cover art image by memory.
+ ///
+ /// @param[in] data Image data
+ /// @param[in] size Image data size
+ /// @param[in] mimetype Image format mimetype
+ /// Possible mimetypes:
+ /// - "image/jpeg"
+ /// - "image/png"
+ /// - "image/gif"
+ /// - "image/bmp"
+ ///
+ void SetCoverArtByMem(const uint8_t* data, size_t size, const std::string& mimetype)
+ {
+ if (size > 0)
+ {
+ m_cover_art_mem_mimetype = mimetype;
+ m_cover_art_mem.resize(size);
+ m_cover_art_mem.assign(data, data + size);
+ }
+ }
+
+ /// @brief Get cover art data by memory.
+ ///
+ /// @param[out] size Stored size about art image
+ /// @param[in] mimetype Related image mimetype to stored data
+ /// @return Image data
+ ///
+ /// @note This only works if @ref SetCoverArtByMem was used before
+ ///
+ /// @warning This function is not thread safe and related data should never be
+ /// changed by @ref SetCoverArtByMem, if data from here is used without copy!
+ const uint8_t* GetCoverArtByMem(size_t& size, std::string& mimetype) const
+ {
+ if (!m_cover_art_mem.empty())
+ {
+ mimetype = m_cover_art_mem_mimetype;
+ size = m_cover_art_mem.size();
+ return m_cover_art_mem.data();
+ }
+ else
+ {
+ size = 0;
+ return nullptr;
+ }
+ }
+
+ ///@}
+
+private:
+ std::string m_title;
+ std::string m_artist;
+ std::string m_album;
+ std::string m_album_artist;
+ std::string m_media_type;
+ std::string m_genre;
+ int m_duration{0};
+ int m_track{0};
+ int m_disc{0};
+ std::string m_disc_subtitle;
+ int m_disc_total{0};
+ std::string m_release_date;
+ std::string m_lyrics;
+ int m_samplerate{0};
+ int m_channels{0};
+ int m_bitrate{0};
+ std::string m_comment;
+ std::string m_cover_art_path;
+ std::string m_cover_art_mem_mimetype;
+ std::vector<uint8_t> m_cover_art_mem;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_audiodecoder_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_audiodecoder
+/// @brief **Audio decoder add-on instance definition values**\n
+/// All audio decoder functions associated data structures.
+///
+/// Used to exchange the available options between Kodi and addon.\n
+/// The groups described here correspond to the groups of functions on audio
+/// decoder instance class.
+///
+
+//==============================================================================
+///
+/// @addtogroup cpp_kodi_addon_audiodecoder
+/// @brief \cpp_class{ kodi::addon::CInstanceAudioDecoder }
+/// **Audio decoder add-on instance**
+///
+/// For audio decoders as binary add-ons. This class implements a way to handle
+/// special types of audio files.
+///
+/// The add-on handles loading of the source file and outputting the audio stream
+/// for consumption by the player.
+///
+/// The addon.xml defines the capabilities of this add-on.
+///
+/// @note The option to have multiple instances is possible with audio-decoder
+/// add-ons. This is useful, since some playback engines are riddled by global
+/// variables, making decoding of multiple streams using the same instance
+/// impossible.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Here's an example on addon.xml:**
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="audiodecoder.myspecialnamefor"
+/// version="1.0.0"
+/// name="My special audio decoder addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="kodi.audiodecoder"
+/// name="2sf"
+/// tags="true"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@">
+/// <support>
+/// <extension name=".2sf">
+/// <description>30100</description>
+/// <icon>resources/file_format_music_sound.png</icon>
+/// </extension>
+/// <extension name=".mini2sf"/>
+/// </support>
+/// </extension>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My audio decoder addon addon</summary>
+/// <description lang="en_GB">My audio decoder addon description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+/// Description to audio decoder related addon.xml values:
+/// | Name | Description
+/// |:------------------------------------------------------|----------------------------------------
+/// | <b>`point`</b> | Addon type specification<br>At all addon types and for this kind always <b>"kodi.audiodecoder"</b>.
+/// | <b>`library_@PLATFORM@`</b> | Sets the used library name, which is automatically set by cmake at addon build.
+/// | <b>`name`</b> | The name of the decoder used in Kodi for display.
+/// | <b>`tags`</b> | Boolean to point out that addon can bring own information to replayed file, if <b>`false`</b> only the file name is used as info.<br>If <b>`true`</b>, @ref CInstanceAudioDecoder::ReadTag is used and must be implemented.
+/// | <b>`tracks`</b> | Boolean to in inform one file can contains several different streams.
+/// | <b>`<support><extension name="..." /></support>`</b> | The file extensions / styles supported by this addon.\nOptional can be with `<description>` and `<icon>`additional info added where used for list views in Kodi.
+/// | <b>`<support><mimetype name="..." /></support>`</b> | A stream URL mimetype where can be used to force to this addon.\nOptional can be with ``<description>` and `<icon>`additional info added where used for list views in Kodi.
+///
+/// --------------------------------------------------------------------------
+///
+/// **Here is a code example how this addon is used:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/AudioDecoder.h>
+///
+/// class CMyAudioDecoder : public kodi::addon::CInstanceAudioDecoder
+/// {
+/// public:
+/// CMyAudioDecoder(const kodi::addon::IInstanceInfo& instance);
+///
+/// bool Init(const std::string& filename, unsigned int filecache,
+/// int& channels, int& samplerate,
+/// int& bitspersample, int64_t& totaltime,
+/// int& bitrate, AudioEngineDataFormat& format,
+/// std::vector<AudioEngineChannel>& channellist) override;
+/// int ReadPCM(uint8_t* buffer, int size, int& actualsize) override;
+/// };
+///
+/// CMyAudioDecoder::CMyAudioDecoder(const kodi::addon::IInstanceInfo& instance)
+/// : kodi::addon::CInstanceAudioDecoder(instance)
+/// {
+/// ...
+/// }
+///
+/// bool CMyAudioDecoder::Init(const std::string& filename, unsigned int filecache,
+/// int& channels, int& samplerate,
+/// int& bitspersample, int64_t& totaltime,
+/// int& bitrate, AudioEngineDataFormat& format,
+/// std::vector<AudioEngineChannel>& channellist)
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// int CMyAudioDecoder::ReadPCM(uint8_t* buffer, int size, int& actualsize)
+/// {
+/// ...
+/// return AUDIODECODER_READ_SUCCESS;
+/// }
+///
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_AUDIODECODER))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my audio decoder");
+/// hdl = new CMyAudioDecoder(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyAudioDecoder` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+class ATTR_DLL_LOCAL CInstanceAudioDecoder : public IAddonInstance
+{
+public:
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Audio decoder class constructor used to support multiple instance
+ /// types.
+ ///
+ /// @param[in] instance The instance value given to
+ /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// class CMyAudioDecoder : public kodi::addon::CInstanceAudioDecoder
+ /// {
+ /// public:
+ /// CMyAudioDecoder(KODI_HANDLE instance)
+ /// : kodi::addon::CInstanceAudioDecoder(instance)
+ /// {
+ /// ...
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ /// KODI_ADDON_INSTANCE_HDL& hdl)
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my audio decoder");
+ /// hdl = new CMyAudioDecoder(instance);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ explicit CInstanceAudioDecoder(const kodi::addon::IInstanceInfo& instance)
+ : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceAudioDecoder: Creation of multiple together with single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Checks addon support given file path.
+ ///
+ /// @param[in] filename The file to read
+ /// @return true if successfully done and supported, otherwise false
+ ///
+ /// @note Optional to add, as default becomes `true` used.
+ ///
+ virtual bool SupportsFile(const std::string& filename) { return true; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Initialize a decoder.
+ ///
+ /// @param[in] filename The file to read
+ /// @param[in] filecache The file cache size
+ /// @param[out] channels Number of channels in output stream
+ /// @param[out] samplerate Samplerate of output stream
+ /// @param[out] bitspersample Bits per sample in output stream
+ /// @param[out] totaltime Total time for stream
+ /// @param[out] bitrate Average bitrate of input stream
+ /// @param[out] format Data format for output stream, see
+ /// @ref cpp_kodi_audioengine_Defs_AudioEngineFormat for
+ /// available values
+ /// @param[out] channellist Channel mapping for output stream, see
+ /// @ref cpp_kodi_audioengine_Defs_AudioEngineChannel
+ /// for available values
+ /// @return true if successfully done, otherwise false
+ ///
+ virtual bool Init(const std::string& filename,
+ unsigned int filecache,
+ int& channels,
+ int& samplerate,
+ int& bitspersample,
+ int64_t& totaltime,
+ int& bitrate,
+ AudioEngineDataFormat& format,
+ std::vector<AudioEngineChannel>& channellist) = 0;
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Produce some noise.
+ ///
+ /// @param[in] buffer Output buffer
+ /// @param[in] size Size of output buffer
+ /// @param[out] actualsize Actual number of bytes written to output buffer
+ /// @return @copydetails cpp_kodi_addon_audiodecoder_Defs_AUDIODECODER_READ_RETURN
+ ///
+ virtual int ReadPCM(uint8_t* buffer, size_t size, size_t& actualsize) = 0;
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Seek in output stream.
+ ///
+ /// @param[in] time Time position to seek to in milliseconds
+ /// @return Time position seek ended up on
+ ///
+ virtual int64_t Seek(int64_t time) { return time; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Read tag of a file.
+ ///
+ /// @param[in] file File to read tag for
+ /// @param[out] tag Information tag about
+ /// @return True on success, false on failure
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_audiodecoder_Defs_AudioDecoderInfoTag_Help
+ ///
+ virtual bool ReadTag(const std::string& file, kodi::addon::AudioDecoderInfoTag& tag)
+ {
+ return false;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Get number of tracks in a file.
+ ///
+ /// @param[in] file File to read tag for
+ /// @return Number of tracks in file
+ ///
+ virtual int TrackCount(const std::string& file) { return 1; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_audiodecoder
+ /// @brief Static auxiliary function to read the track number used from the
+ /// given path.
+ ///
+ /// If track number is not found in file name, the originally given file
+ /// name is returned, track number then remains at "0".
+ ///
+ /// @param[in] name The value specified in addon.xml extension under `name="???"`
+ /// @param[in] trackPath The full path to evaluate
+ /// @param[out] track The track number read out in the path, 0 if not
+ /// identified as a track path.
+ /// @return Path to the associated file
+ ///
+ inline static std::string GetTrack(const std::string& name,
+ const std::string& trackPath,
+ int& track)
+ {
+ /*
+ * get the track name from path
+ */
+ track = 0;
+ std::string toLoad(trackPath);
+ const std::string ext = "." + name + KODI_ADDON_AUDIODECODER_TRACK_EXT;
+ if (toLoad.find(ext) != std::string::npos)
+ {
+ size_t iStart = toLoad.rfind('-') + 1;
+ track = atoi(toLoad.substr(iStart, toLoad.size() - iStart - ext.size()).c_str());
+ // The directory we are in, is the file
+ // that contains the bitstream to play,
+ // so extract it
+ size_t slash = trackPath.rfind('\\');
+ if (slash == std::string::npos)
+ slash = trackPath.rfind('/');
+ toLoad = trackPath.substr(0, slash);
+ }
+
+ return toLoad;
+ }
+ //--------------------------------------------------------------------------
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+ instance->audiodecoder->toAddon->supports_file = ADDON_supports_file;
+ instance->audiodecoder->toAddon->init = ADDON_init;
+ instance->audiodecoder->toAddon->read_pcm = ADDON_read_pcm;
+ instance->audiodecoder->toAddon->seek = ADDON_seek;
+ instance->audiodecoder->toAddon->read_tag = ADDON_read_tag;
+ instance->audiodecoder->toAddon->track_count = ADDON_track_count;
+ }
+
+ inline static bool ADDON_supports_file(const KODI_ADDON_AUDIODECODER_HDL hdl, const char* file)
+ {
+ return static_cast<CInstanceAudioDecoder*>(hdl)->SupportsFile(file);
+ }
+
+ inline static bool ADDON_init(const KODI_ADDON_AUDIODECODER_HDL hdl,
+ const char* file,
+ unsigned int filecache,
+ int* channels,
+ int* samplerate,
+ int* bitspersample,
+ int64_t* totaltime,
+ int* bitrate,
+ AudioEngineDataFormat* format,
+ enum AudioEngineChannel info[AUDIOENGINE_CH_MAX])
+ {
+ CInstanceAudioDecoder* thisClass = static_cast<CInstanceAudioDecoder*>(hdl);
+
+ std::vector<AudioEngineChannel> channelList;
+
+ bool ret = thisClass->Init(file, filecache, *channels, *samplerate, *bitspersample, *totaltime,
+ *bitrate, *format, channelList);
+ if (!channelList.empty())
+ {
+ if (channelList.back() != AUDIOENGINE_CH_NULL)
+ channelList.push_back(AUDIOENGINE_CH_NULL);
+
+ for (unsigned int i = 0; i < channelList.size(); ++i)
+ {
+ info[i] = channelList[i];
+ }
+ }
+ return ret;
+ }
+
+ inline static int ADDON_read_pcm(const KODI_ADDON_AUDIODECODER_HDL hdl,
+ uint8_t* buffer,
+ size_t size,
+ size_t* actualsize)
+ {
+ return static_cast<CInstanceAudioDecoder*>(hdl)->ReadPCM(buffer, size, *actualsize);
+ }
+
+ inline static int64_t ADDON_seek(const KODI_ADDON_AUDIODECODER_HDL hdl, int64_t time)
+ {
+ return static_cast<CInstanceAudioDecoder*>(hdl)->Seek(time);
+ }
+
+ inline static bool ADDON_read_tag(const KODI_ADDON_AUDIODECODER_HDL hdl,
+ const char* file,
+ struct KODI_ADDON_AUDIODECODER_INFO_TAG* tag)
+ {
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable : 4996)
+#endif // _WIN32
+ kodi::addon::AudioDecoderInfoTag cppTag;
+ bool ret = static_cast<CInstanceAudioDecoder*>(hdl)->ReadTag(file, cppTag);
+ if (ret)
+ {
+ tag->title = strdup(cppTag.GetTitle().c_str());
+ tag->artist = strdup(cppTag.GetArtist().c_str());
+ tag->album = strdup(cppTag.GetAlbum().c_str());
+ tag->album_artist = strdup(cppTag.GetAlbumArtist().c_str());
+ tag->media_type = strdup(cppTag.GetMediaType().c_str());
+ tag->genre = strdup(cppTag.GetGenre().c_str());
+ tag->duration = cppTag.GetDuration();
+ tag->track = cppTag.GetTrack();
+ tag->disc = cppTag.GetDisc();
+ tag->disc_subtitle = strdup(cppTag.GetDiscSubtitle().c_str());
+ tag->disc_total = cppTag.GetDiscTotal();
+ tag->release_date = strdup(cppTag.GetReleaseDate().c_str());
+ tag->lyrics = strdup(cppTag.GetLyrics().c_str());
+ tag->samplerate = cppTag.GetSamplerate();
+ tag->channels = cppTag.GetChannels();
+ tag->bitrate = cppTag.GetBitrate();
+ tag->comment = strdup(cppTag.GetComment().c_str());
+ std::string mimetype;
+ size_t size = 0;
+ const uint8_t* mem = cppTag.GetCoverArtByMem(size, mimetype);
+ if (mem && size > 0)
+ {
+ tag->cover_art_mem_mimetype = strdup(mimetype.c_str());
+ tag->cover_art_mem_size = size;
+ tag->cover_art_mem = static_cast<uint8_t*>(malloc(size));
+ memcpy(tag->cover_art_mem, mem, size);
+ }
+ else
+ {
+ tag->cover_art_path = strdup(cppTag.GetCoverArtByPath().c_str());
+ }
+ }
+ return ret;
+#ifdef _WIN32
+#pragma warning(pop)
+#endif // _WIN32
+ }
+
+ inline static int ADDON_track_count(const KODI_ADDON_AUDIODECODER_HDL hdl, const char* file)
+ {
+ return static_cast<CInstanceAudioDecoder*>(hdl)->TrackCount(file);
+ }
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioEncoder.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioEncoder.h
new file mode 100644
index 0000000..c79a472
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioEncoder.h
@@ -0,0 +1,514 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/addon-instance/audioencoder.h"
+
+#ifdef __cplusplus
+
+#include <stdexcept>
+
+namespace kodi
+{
+namespace addon
+{
+
+class CInstanceAudioEncoder;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_audioencoder_Defs_AudioEncoderInfoTag class AudioEncoderInfoTag
+/// @ingroup cpp_kodi_addon_audioencoder_Defs
+/// @brief **Info tag data structure**\n
+/// Representation of available information of processed audio file.
+///
+/// This is used to get all the necessary data of audio stream and to have on
+/// created files by encoders.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_audioencoder_Defs_AudioEncoderInfoTag_Help
+///
+///@{
+class ATTR_DLL_LOCAL AudioEncoderInfoTag
+{
+public:
+ /*! \cond PRIVATE */
+ AudioEncoderInfoTag() = default;
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_audioencoder_Defs_AudioEncoderInfoTag_Help Value Help
+ /// @ingroup cpp_kodi_addon_audioencoder_Defs_AudioEncoderInfoTag
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_audioencoder_Defs_AudioEncoderInfoTag :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Title** | `std::string` | @ref AudioEncoderInfoTag::SetTitle "SetTitle" | @ref AudioEncoderInfoTag::GetTitle "GetTitle"
+ /// | **Artist** | `std::string` | @ref AudioEncoderInfoTag::SetArtist "SetArtist" | @ref AudioEncoderInfoTag::GetArtist "GetArtist"
+ /// | **Album** | `std::string` | @ref AudioEncoderInfoTag::SetAlbum "SetAlbum" | @ref AudioEncoderInfoTag::GetAlbum "GetAlbum"
+ /// | **Album artist** | `std::string` | @ref AudioEncoderInfoTag::SetAlbumArtist "SetAlbumArtist" | @ref AudioEncoderInfoTag::GetAlbumArtist "GetAlbumArtist"
+ /// | **Media type** | `std::string` | @ref AudioEncoderInfoTag::SetMediaType "SetMediaType" | @ref AudioEncoderInfoTag::GetMediaType "GetMediaType"
+ /// | **Genre** | `std::string` | @ref AudioEncoderInfoTag::SetGenre "SetGenre" | @ref AudioEncoderInfoTag::GetGenre "GetGenre"
+ /// | **Duration** | `int` | @ref AudioEncoderInfoTag::SetDuration "SetDuration" | @ref AudioEncoderInfoTag::GetDuration "GetDuration"
+ /// | **Track number** | `int` | @ref AudioEncoderInfoTag::SetTrack "SetTrack" | @ref AudioEncoderInfoTag::GetTrack "GetTrack"
+ /// | **Disc number** | `int` | @ref AudioEncoderInfoTag::SetDisc "SetDisc" | @ref AudioEncoderInfoTag::GetDisc "GetDisc"
+ /// | **Disc subtitle name** | `std::string` | @ref AudioEncoderInfoTag::SetDiscSubtitle "SetDiscSubtitle" | @ref AudioEncoderInfoTag::GetDiscSubtitle "GetDiscSubtitle"
+ /// | **Disc total amount** | `int` | @ref AudioEncoderInfoTag::SetDiscTotal "SetDiscTotal" | @ref AudioEncoderInfoTag::GetDiscTotal "GetDiscTotal"
+ /// | **Release date** | `std::string` | @ref AudioEncoderInfoTag::SetReleaseDate "SetReleaseDate" | @ref AudioEncoderInfoTag::GetReleaseDate "GetReleaseDate"
+ /// | **Lyrics** | `std::string` | @ref AudioEncoderInfoTag::SetLyrics "SetLyrics" | @ref AudioEncoderInfoTag::GetLyrics "GetLyrics"
+ /// | **Samplerate** | `int` | @ref AudioEncoderInfoTag::SetSamplerate "SetSamplerate" | @ref AudioEncoderInfoTag::GetSamplerate "GetSamplerate"
+ /// | **Channels amount** | `int` | @ref AudioEncoderInfoTag::SetChannels "SetChannels" | @ref AudioEncoderInfoTag::GetChannels "GetChannels"
+ /// | **Bits per sample** | `int` | @ref AudioEncoderInfoTag::SetBitsPerSample "SetBitsPerSample" | @ref AudioEncoderInfoTag::GetBitsPerSample "GetBitsPerSample"
+ /// | **Track length** | `int` | @ref AudioEncoderInfoTag::SetTrackLength "SetTrackLength" | @ref AudioEncoderInfoTag::GetTrackLength "GetTrackLength"
+ /// | **Comment text** | `std::string` | @ref AudioEncoderInfoTag::SetComment "SetComment" | @ref AudioEncoderInfoTag::GetComment "GetComment"
+ ///
+ /// @addtogroup cpp_kodi_addon_audioencoder_Defs_AudioEncoderInfoTag
+ ///@{
+
+ /// @brief Set the title from music as string on info tag.
+ void SetTitle(const std::string& title) { m_title = title; }
+
+ /// @brief Get title name
+ const std::string& GetTitle() const { return m_title; }
+
+ /// @brief Set artist name
+ void SetArtist(const std::string& artist) { m_artist = artist; }
+
+ /// @brief Get artist name
+ const std::string& GetArtist() const { return m_artist; }
+
+ /// @brief Set album name
+ void SetAlbum(const std::string& album) { m_album = album; }
+
+ /// @brief Get album name
+ const std::string& GetAlbum() const { return m_album; }
+
+ /// @brief Set album artist name
+ void SetAlbumArtist(const std::string& albumArtist) { m_album_artist = albumArtist; }
+
+ /// @brief Get album artist name
+ const std::string& GetAlbumArtist() const { return m_album_artist; }
+
+ /// @brief Set the media type of the music item.
+ ///
+ /// Available strings about media type for music:
+ /// | String | Description |
+ /// |---------------:|:--------------------------------------------------|
+ /// | artist | If it is defined as an artist
+ /// | album | If it is defined as an album
+ /// | music | If it is defined as an music
+ /// | song | If it is defined as a song
+ ///
+ void SetMediaType(const std::string& mediaType) { m_media_type = mediaType; }
+
+ /// @brief Get the media type of the music item.
+ const std::string& GetMediaType() const { return m_media_type; }
+
+ /// @brief Set genre name from music as string if present.
+ void SetGenre(const std::string& genre) { m_genre = genre; }
+
+ /// @brief Get genre name from music as string if present.
+ const std::string& GetGenre() const { return m_genre; }
+
+ /// @brief Set the duration of music as integer from info.
+ void SetDuration(int duration) { m_duration = duration; }
+
+ /// @brief Get the duration of music as integer from info.
+ int GetDuration() const { return m_duration; }
+
+ /// @brief Set track number (if present) from music info as integer.
+ void SetTrack(int track) { m_track = track; }
+
+ /// @brief Get track number (if present).
+ int GetTrack() const { return m_track; }
+
+ /// @brief Set disk number (if present) from music info as integer.
+ void SetDisc(int disc) { m_disc = disc; }
+
+ /// @brief Get disk number (if present)
+ int GetDisc() const { return m_disc; }
+
+ /// @brief Set disk subtitle name (if present) from music info.
+ void SetDiscSubtitle(const std::string& discSubtitle) { m_disc_subtitle = discSubtitle; }
+
+ /// @brief Get disk subtitle name (if present) from music info.
+ const std::string& GetDiscSubtitle() const { return m_disc_subtitle; }
+
+ /// @brief Set disks amount quantity (if present) from music info as integer.
+ void SetDiscTotal(int discTotal) { m_disc_total = discTotal; }
+
+ /// @brief Get disks amount quantity (if present)
+ int GetDiscTotal() const { return m_disc_total; }
+
+ /// @brief Set release date as string from music info (if present).\n
+ /// [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) date YYYY, YYYY-MM or YYYY-MM-DD
+ void SetReleaseDate(const std::string& releaseDate) { m_release_date = releaseDate; }
+
+ /// @brief Get release date as string from music info (if present).
+ const std::string& GetReleaseDate() const { return m_release_date; }
+
+ /// @brief Set string from lyrics.
+ void SetLyrics(const std::string& lyrics) { m_lyrics = lyrics; }
+
+ /// @brief Get string from lyrics.
+ const std::string& GetLyrics() const { return m_lyrics; }
+
+ /// @brief Set related stream samplerate.
+ void SetSamplerate(int samplerate) { m_samplerate = samplerate; }
+
+ /// @brief Get related stream samplerate.
+ int GetSamplerate() const { return m_samplerate; }
+
+ /// @brief Set related stream channels amount.
+ void SetChannels(int channels) { m_channels = channels; }
+
+ /// @brief Get related stream channels amount.
+ int GetChannels() const { return m_channels; }
+
+ /// @brief Set related stream bits per sample.
+ void SetBitsPerSample(int bits_per_sample) { m_bits_per_sample = bits_per_sample; }
+
+ /// @brief Get related stream bits per sample.
+ int GetBitsPerSample() const { return m_bits_per_sample; }
+
+ /// @brief Set related stream track length.
+ void SetTrackLength(int track_length) { m_track_length = track_length; }
+
+ /// @brief Get related stream track length.
+ int GetTrackLength() const { return m_track_length; }
+
+ /// @brief Set additional information comment (if present).
+ void SetComment(const std::string& comment) { m_comment = comment; }
+
+ /// @brief Get additional information comment (if present).
+ const std::string& GetComment() const { return m_comment; }
+
+ ///@}
+
+private:
+ friend class CInstanceAudioEncoder;
+
+ AudioEncoderInfoTag(const struct KODI_ADDON_AUDIOENCODER_INFO_TAG* tag)
+ {
+ if (tag->title)
+ m_title = tag->title;
+ if (tag->artist)
+ m_artist = tag->artist;
+ if (tag->album)
+ m_album = tag->album;
+ if (tag->album_artist)
+ m_album_artist = tag->album_artist;
+ if (tag->media_type)
+ m_media_type = tag->media_type;
+ if (tag->genre)
+ m_genre = tag->genre;
+ m_duration = tag->duration;
+ m_track = tag->track;
+ m_disc = tag->disc;
+ if (tag->artist)
+ m_disc_subtitle = tag->artist;
+ m_disc_total = tag->disc_total;
+ if (tag->release_date)
+ m_release_date = tag->release_date;
+ if (tag->lyrics)
+ m_lyrics = tag->lyrics;
+ m_samplerate = tag->samplerate;
+ m_channels = tag->channels;
+ m_bits_per_sample = tag->bits_per_sample;
+ m_track_length = tag->track_length;
+ if (tag->comment)
+ m_comment = tag->comment;
+ }
+
+ std::string m_title;
+ std::string m_artist;
+ std::string m_album;
+ std::string m_album_artist;
+ std::string m_media_type;
+ std::string m_genre;
+ int m_duration{0};
+ int m_track{0};
+ int m_disc{0};
+ std::string m_disc_subtitle;
+ int m_disc_total{0};
+ std::string m_release_date;
+ std::string m_lyrics;
+ int m_samplerate{0};
+ int m_channels{0};
+ int m_bits_per_sample{0};
+ int m_track_length{0};
+ std::string m_comment;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @addtogroup cpp_kodi_addon_audioencoder
+/// @brief \cpp_class{ kodi::addon::CInstanceAudioEncoder }
+/// **Audio encoder add-on instance.**\n
+/// For audio encoders as binary add-ons. This class implements a way to handle
+/// the encode of given stream to a new format.
+///
+/// The addon.xml defines the capabilities of this add-on.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Here's an example on addon.xml:**
+/// ~~~~~~~~~~~~~{.xml}
+/// <extension
+/// point="kodi.audioencoder"
+/// extension=".flac"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
+/// ~~~~~~~~~~~~~
+///
+/// Description to audio encoder related addon.xml values:
+/// | Name | Description
+/// |:------------------------------|----------------------------------------
+/// | <b>`point`</b> | Addon type specification<br>At all addon types and for this kind always <b>"kodi.audioencoder"</b>.
+/// | <b>`library_@PLATFORM@`</b> | Sets the used library name, which is automatically set by cmake at addon build.
+/// | <b>`extension`</b> | The file extensions / styles supported by this addon.
+///
+/// --------------------------------------------------------------------------
+///
+/// --------------------------------------------------------------------------
+///
+/// **Here is a code example how this addon is used:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/AudioEncoder.h>
+///
+/// class ATTR_DLL_LOCAL CMyAudioEncoder : public kodi::addon::CInstanceAudioEncoder
+/// {
+/// public:
+/// CMyAudioEncoder(const kodi::addon::IInstanceInfo& instance);
+///
+/// bool Start(const kodi::addon::AudioEncoderInfoTag& tag) override;
+/// int Encode(int numBytesRead, const uint8_t* pbtStream) override;
+/// bool Finish() override; // Optional
+/// };
+///
+/// CMyAudioEncoder::CMyAudioEncoder(const kodi::addon::IInstanceInfo& instance)
+/// : kodi::addon::CInstanceAudioEncoder(instance)
+/// {
+/// ...
+/// }
+///
+/// bool CMyAudioEncoder::Start(const kodi::addon::AudioEncoderInfoTag& tag)
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// ssize_t CMyAudioEncoder::Encode(const uint8_t* pbtStream, size_t numBytesRead)
+/// {
+/// uint8_t* data = nullptr;
+/// size_t length = 0;
+/// ...
+/// kodi::addon::CInstanceAudioEncoder::Write(data, length);
+///
+/// return 0;
+/// }
+///
+///
+/// bool CMyAudioEncoder::Finish()
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_AUDIOENCODER))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my audio encoder instance");
+/// hdl = new CMyAudioEncoder(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyAudioEncoder` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+class ATTR_DLL_LOCAL CInstanceAudioEncoder : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_audioencoder
+ /// @brief Audio encoder class constructor used to support multiple instances.
+ ///
+ /// @param[in] instance The instance value given to
+ /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// class CMyAudioEncoder : public kodi::addon::CInstanceAudioEncoder
+ /// {
+ /// public:
+ /// CMyAudioEncoder(const kodi::addon::IInstanceInfo& instance)
+ /// : kodi::addon::CInstanceAudioEncoder(instance)
+ /// {
+ /// ...
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ /// KODI_ADDON_INSTANCE_HDL& hdl)
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my audio encoder instance");
+ /// hdl = new CMyAudioEncoder(instance);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ explicit CInstanceAudioEncoder(const kodi::addon::IInstanceInfo& instance)
+ : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceAudioEncoder: Creation of multiple together "
+ "with single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_audioencoder
+ /// @brief Start encoder (**required**)
+ ///
+ /// @param[in] tag Information tag about
+ /// @return True on success, false on failure.
+ ///
+ virtual bool Start(const kodi::addon::AudioEncoderInfoTag& tag) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_audioencoder
+ /// @brief Encode a chunk of audio (**required**)
+ ///
+ /// @param[in] pbtStream The input buffer
+ /// @param[in] numBytesRead Number of bytes in input buffer
+ /// @return Number of bytes consumed
+ ///
+ virtual ssize_t Encode(const uint8_t* pbtStream, size_t numBytesRead) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_audioencoder
+ /// @brief Finalize encoding (**optional**)
+ ///
+ /// @return True on success, false on failure.
+ ///
+ virtual bool Finish() { return true; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_audioencoder
+ /// @brief Write block of data
+ ///
+ /// @param[in] data Pointer to the array of elements to be written
+ /// @param[in] length Size in bytes to be written.
+ /// @return The total number of bytes successfully written is returned.
+ ///
+ /// @remarks Only called from addon itself.
+ ///
+ ssize_t Write(const uint8_t* data, size_t length)
+ {
+ return m_kodi->write(m_kodi->kodiInstance, data, length);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_audioencoder
+ /// @brief Set the file's current position.
+ ///
+ /// The whence argument is optional and defaults to SEEK_SET (0)
+ ///
+ /// @param[in] position The position that you want to seek to
+ /// @param[in] whence [optional] offset relative to\n
+ /// You can set the value of whence to one
+ /// of three things:
+ /// | Value | int | Description |
+ /// |:--------:|:---:|:---------------------------------------------------|
+ /// | SEEK_SET | 0 | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
+ /// | SEEK_CUR | 1 | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
+ /// | SEEK_END | 2 | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
+ ///
+ /// @return Returns the resulting offset location as measured in bytes from
+ /// the beginning of the file. On error, the value -1 is returned.
+ ///
+ /// @remarks Only called from addon itself.
+ ///
+ ssize_t Seek(ssize_t position, int whence = SEEK_SET)
+ {
+ return m_kodi->seek(m_kodi->kodiInstance, position, whence);
+ }
+ //----------------------------------------------------------------------------
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+ instance->audioencoder->toAddon->start = ADDON_start;
+ instance->audioencoder->toAddon->encode = ADDON_encode;
+ instance->audioencoder->toAddon->finish = ADDON_finish;
+ m_kodi = instance->audioencoder->toKodi;
+ }
+
+ inline static bool ADDON_start(const KODI_ADDON_AUDIOENCODER_HDL hdl,
+ const struct KODI_ADDON_AUDIOENCODER_INFO_TAG* tag)
+ {
+ return static_cast<CInstanceAudioEncoder*>(hdl)->Start(tag);
+ }
+
+ inline static ssize_t ADDON_encode(const KODI_ADDON_AUDIOENCODER_HDL hdl,
+ const uint8_t* pbtStream,
+ size_t num_bytes_read)
+ {
+ return static_cast<CInstanceAudioEncoder*>(hdl)->Encode(pbtStream, num_bytes_read);
+ }
+
+ inline static bool ADDON_finish(const KODI_ADDON_AUDIOENCODER_HDL hdl)
+ {
+ return static_cast<CInstanceAudioEncoder*>(hdl)->Finish();
+ }
+
+ AddonToKodiFuncTable_AudioEncoder* m_kodi{nullptr};
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/CMakeLists.txt
new file mode 100644
index 0000000..8f7d20c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ AudioDecoder.h
+ AudioEncoder.h
+ Game.h
+ ImageDecoder.h
+ Inputstream.h
+ PVR.h
+ Peripheral.h
+ Screensaver.h
+ VFS.h
+ VideoCodec.h
+ Visualization.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_addon-instance)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h
new file mode 100644
index 0000000..b4f1a24
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h
@@ -0,0 +1,1432 @@
+/*
+ * Copyright (C) 2014-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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/addon-instance/game.h"
+
+#include <algorithm>
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @addtogroup cpp_kodi_addon_game
+///
+/// To use on Libretro and for stand-alone games or emulators that does not use
+/// the Libretro API.
+///
+/// Possible examples could be, Nvidia GameStream via Limelight or WINE capture
+/// could possible through the Game API.
+///
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_game_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_game
+/// @brief **Game add-on instance definition values**
+///
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_game_Defs_InputTypes_GameControllerLayout class GameControllerLayout
+/// @ingroup cpp_kodi_addon_game_Defs_InputTypes
+/// @brief Data of layouts for known controllers.
+///
+/// Used on @ref kodi::addon::CInstanceGame::SetControllerLayouts().
+///@{
+class GameControllerLayout
+{
+public:
+ /*! @cond PRIVATE */
+ explicit GameControllerLayout() = default;
+ GameControllerLayout(const game_controller_layout& layout) : controller_id(layout.controller_id)
+ {
+ provides_input = layout.provides_input;
+ for (unsigned int i = 0; i < layout.digital_button_count; ++i)
+ digital_buttons.push_back(layout.digital_buttons[i]);
+ for (unsigned int i = 0; i < layout.analog_button_count; ++i)
+ analog_buttons.push_back(layout.analog_buttons[i]);
+ for (unsigned int i = 0; i < layout.analog_stick_count; ++i)
+ analog_sticks.push_back(layout.analog_sticks[i]);
+ for (unsigned int i = 0; i < layout.accelerometer_count; ++i)
+ accelerometers.push_back(layout.accelerometers[i]);
+ for (unsigned int i = 0; i < layout.key_count; ++i)
+ keys.push_back(layout.keys[i]);
+ for (unsigned int i = 0; i < layout.rel_pointer_count; ++i)
+ rel_pointers.push_back(layout.rel_pointers[i]);
+ for (unsigned int i = 0; i < layout.abs_pointer_count; ++i)
+ abs_pointers.push_back(layout.abs_pointers[i]);
+ for (unsigned int i = 0; i < layout.motor_count; ++i)
+ motors.push_back(layout.motors[i]);
+ }
+ /*! @endcond */
+
+ /// @brief Controller identifier.
+ std::string controller_id;
+
+ /// @brief Provides input.
+ ///
+ /// False for multitaps
+ bool provides_input{false};
+
+ /// @brief Digital buttons.
+ std::vector<std::string> digital_buttons;
+
+ /// @brief Analog buttons.
+ std::vector<std::string> analog_buttons;
+
+ /// @brief Analog sticks.
+ std::vector<std::string> analog_sticks;
+
+ /// @brief Accelerometers.
+ std::vector<std::string> accelerometers;
+
+ /// @brief Keys.
+ std::vector<std::string> keys;
+
+ /// @brief Relative pointers.
+ std::vector<std::string> rel_pointers;
+
+ /// @brief Absolute pointers.
+ std::vector<std::string> abs_pointers;
+
+ /// @brief Motors.
+ std::vector<std::string> motors;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @addtogroup cpp_kodi_addon_game
+/// @brief @cpp_class{ kodi::addon::CInstanceGame }
+/// **Game add-on instance**\n
+/// This class provides the basic game processing system for use as an add-on in
+/// Kodi.
+///
+/// This class is created at addon by Kodi.
+///
+class ATTR_DLL_LOCAL CInstanceGame : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_game_Base 1. Basic functions
+ /// @ingroup cpp_kodi_addon_game
+ /// @brief **Functions to manage the addon and get basic information about it**
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Game class constructor
+ ///
+ /// Used by an add-on that only supports only Game and only in one instance.
+ ///
+ /// This class is created at addon by Kodi.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/addon-instance/Game.h>
+ /// ...
+ ///
+ /// class ATTR_DLL_LOCAL CGameExample
+ /// : public kodi::addon::CAddonBase,
+ /// public kodi::addon::CInstanceGame
+ /// {
+ /// public:
+ /// CGameExample()
+ /// {
+ /// }
+ ///
+ /// virtual ~CGameExample();
+ /// {
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDONCREATOR(CGameExample)
+ /// ~~~~~~~~~~~~~
+ ///
+ CInstanceGame() : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceGame: Creation of more as one in single "
+ "instance way is not allowed!");
+
+ SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
+ CPrivateBase::m_interface->globalSingleInstance = this;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Destructor
+ ///
+ ~CInstanceGame() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// The path of the game client being loaded.
+ ///
+ /// @return the used game client Dll path
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ std::string GameClientDllPath() const { return m_instanceData->props->game_client_dll_path; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Paths to proxy DLLs used to load the game client.
+ ///
+ /// @param[out] paths vector list to store available dll paths
+ /// @return true if success and dll paths present
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool ProxyDllPaths(std::vector<std::string>& paths)
+ {
+ for (unsigned int i = 0; i < m_instanceData->props->proxy_dll_count; ++i)
+ {
+ if (m_instanceData->props->proxy_dll_paths[i] != nullptr)
+ paths.push_back(m_instanceData->props->proxy_dll_paths[i]);
+ }
+ return !paths.empty();
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// The "system" directories of the frontend.
+ ///
+ /// These directories can be used to store system-specific ROMs such as
+ /// BIOSes, configuration data, etc.
+ ///
+ /// @return the used resource directory
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool ResourceDirectories(std::vector<std::string>& dirs)
+ {
+ for (unsigned int i = 0; i < m_instanceData->props->resource_directory_count; ++i)
+ {
+ if (m_instanceData->props->resource_directories[i] != nullptr)
+ dirs.push_back(m_instanceData->props->resource_directories[i]);
+ }
+ return !dirs.empty();
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// The writable directory of the frontend.
+ ///
+ /// This directory can be used to store SRAM, memory cards, high scores,
+ /// etc, if the game client cannot use the regular memory interface,
+ /// GetMemoryData().
+ ///
+ /// @return the used profile directory
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ std::string ProfileDirectory() const { return m_instanceData->props->profile_directory; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// The value of the <supports_vfs> property from addon.xml.
+ ///
+ /// @return true if VFS is supported
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool SupportsVFS() const { return m_instanceData->props->supports_vfs; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// The extensions in the <extensions> property from addon.xml.
+ ///
+ /// @param[out] extensions vector list to store available extension
+ /// @return true if success and extensions present
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool Extensions(std::vector<std::string>& extensions)
+ {
+ for (unsigned int i = 0; i < m_instanceData->props->extension_count; ++i)
+ {
+ if (m_instanceData->props->extensions[i] != nullptr)
+ extensions.push_back(m_instanceData->props->extensions[i]);
+ }
+ return !extensions.empty();
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+//--==----==----==----==----==----==----==----==----==----==----==----==----==--
+
+ //============================================================================
+ ///
+ /// @defgroup cpp_kodi_addon_game_Operation 2. Game operations
+ /// @ingroup cpp_kodi_addon_game
+ /// @brief **Game operations**
+ ///
+ /// These are mandatory functions for using this addon to get the available
+ /// channels.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Game operation parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_game_Operation_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_game_Operation_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Load a game
+ ///
+ /// @param[in] url The URL to load
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was loaded
+ ///
+ virtual GAME_ERROR LoadGame(const std::string& url)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Load a game that requires multiple files
+ ///
+ /// @param[in] type The game type
+ /// @param[in] urls An array of urls
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was loaded
+ ///
+ virtual GAME_ERROR LoadGameSpecial(SPECIAL_GAME_TYPE type, const std::vector<std::string>& urls)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Begin playing without a game file
+ ///
+ /// If the add-on supports standalone mode, it must add the <supports_standalone>
+ /// tag to the extension point in addon.xml:
+ ///
+ /// <supports_no_game>false</supports_no_game>
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game add-on was loaded
+ ///
+ virtual GAME_ERROR LoadStandalone()
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Unload the current game
+ ///
+ /// Unloads a currently loaded game
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was unloaded
+ ///
+ virtual GAME_ERROR UnloadGame()
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get timing information about the loaded game
+ ///
+ /// @param[out] timing_info The info structure to fill
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if info was filled
+ ///
+ virtual GAME_ERROR GetGameTiming(game_system_timing& timing_info)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get region of the loaded game
+ ///
+ /// @return the region, or @ref GAME_REGION_UNKNOWN if unknown or no game is loaded
+ ///
+ virtual GAME_REGION GetRegion()
+ {
+ return GAME_REGION_UNKNOWN;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Return true if the client requires the frontend to provide a game loop
+ ///
+ /// The game loop is a thread that calls RunFrame() in a loop at a rate
+ /// determined by the playback speed and the client's FPS.
+ ///
+ /// @return true if the frontend should provide a game loop, false otherwise
+ ///
+ virtual bool RequiresGameLoop()
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Run a single frame for add-ons that use a game loop
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if there was no error
+ ///
+ virtual GAME_ERROR RunFrame()
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Reset the current game
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was reset
+ ///
+ virtual GAME_ERROR Reset()
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Requests the frontend to stop the current game
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ void CloseGame(void) { m_instanceData->toKodi->CloseGame(m_instanceData->toKodi->kodiInstance); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_game_Operation_CStream Class: CStream
+ /// @ingroup cpp_kodi_addon_game_Operation
+ /// @brief @cpp_class{ kodi::addon::CInstanceGame::CStream }
+ /// **Game stream handler**
+ ///
+ /// This class will be integrated into the addon, which can then open it if
+ /// necessary for the processing of an audio or video stream.
+ ///
+ ///
+ /// @note Callback to Kodi class
+ ///@{
+ class CStream
+ {
+ public:
+ CStream() = default;
+
+ CStream(const game_stream_properties& properties)
+ {
+ Open(properties);
+ }
+
+ ~CStream()
+ {
+ Close();
+ }
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_game_Operation_CStream
+ /// @brief Create a stream for gameplay data
+ ///
+ /// @param[in] properties The stream properties
+ /// @return A stream handle, or `nullptr` on failure
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool Open(const game_stream_properties& properties)
+ {
+ if (!CPrivateBase::m_interface->globalSingleInstance)
+ return false;
+
+ if (m_handle)
+ {
+ kodi::Log(ADDON_LOG_INFO, "kodi::addon::CInstanceGame::CStream already becomes reopened");
+ Close();
+ }
+
+ AddonToKodiFuncTable_Game& cb =
+ *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
+ ->m_instanceData->toKodi;
+ m_handle = cb.OpenStream(cb.kodiInstance, &properties);
+ return m_handle != nullptr;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_game_Operation_CStream
+ /// @brief Free the specified stream
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ void Close()
+ {
+ if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
+ return;
+
+ AddonToKodiFuncTable_Game& cb =
+ *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
+ ->m_instanceData->toKodi;
+ cb.CloseStream(cb.kodiInstance, m_handle);
+ m_handle = nullptr;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_game_Operation_CStream
+ /// @brief Get a buffer for zero-copy stream data
+ ///
+ /// @param[in] width The framebuffer width, or 0 for no width specified
+ /// @param[in] height The framebuffer height, or 0 for no height specified
+ /// @param[out] buffer The buffer, or unmodified if false is returned
+ /// @return True if buffer was set, false otherwise
+ ///
+ /// @note If this returns true, buffer must be freed using @ref ReleaseBuffer().
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool GetBuffer(unsigned int width, unsigned int height, game_stream_buffer& buffer)
+ {
+ if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
+ return false;
+
+ AddonToKodiFuncTable_Game& cb =
+ *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
+ ->m_instanceData->toKodi;
+ return cb.GetStreamBuffer(cb.kodiInstance, m_handle, width, height, &buffer);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_game_Operation_CStream
+ /// @brief Add a data packet to a stream
+ ///
+ /// @param[in] packet The data packet
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ void AddData(const game_stream_packet& packet)
+ {
+ if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
+ return;
+
+ AddonToKodiFuncTable_Game& cb =
+ *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
+ ->m_instanceData->toKodi;
+ cb.AddStreamData(cb.kodiInstance, m_handle, &packet);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_game_Operation_CStream
+ /// @brief Free an allocated buffer
+ ///
+ /// @param[in] buffer The buffer returned from GetStreamBuffer()
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ void ReleaseBuffer(game_stream_buffer& buffer)
+ {
+ if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
+ return;
+
+ AddonToKodiFuncTable_Game& cb =
+ *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
+ ->m_instanceData->toKodi;
+ cb.ReleaseStreamBuffer(cb.kodiInstance, m_handle, &buffer);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_game_Operation_CStream
+ /// @brief To check stream open was OK, e.g. after use of constructor
+ ///
+ /// @return true if stream was successfully opened
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool IsOpen() const { return m_handle != nullptr; }
+ //--------------------------------------------------------------------------
+
+ private:
+ KODI_GAME_STREAM_HANDLE m_handle = nullptr;
+ };
+ ///@}
+
+ ///@}
+
+//--==----==----==----==----==----==----==----==----==----==----==----==----==--
+
+ //============================================================================
+ ///
+ /// @defgroup cpp_kodi_addon_game_HardwareRendering 3. Hardware rendering operations
+ /// @ingroup cpp_kodi_addon_game
+ /// @brief **Hardware rendering operations**
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Hardware rendering operation parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_game_HardwareRendering_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_game_HardwareRendering_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Invalidates the current HW context and reinitializes GPU resources
+ ///
+ /// Any GL state is lost, and must not be deinitialized explicitly.
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the HW context was reset
+ ///
+ virtual GAME_ERROR HwContextReset()
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Called before the context is destroyed
+ ///
+ /// Resources can be deinitialized at this step.
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the HW context was destroyed
+ ///
+ virtual GAME_ERROR HwContextDestroy()
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**<br>Get a symbol from the hardware context
+ ///
+ /// @param[in] sym The symbol's name
+ ///
+ /// @return A function pointer for the specified symbol
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ game_proc_address_t HwGetProcAddress(const char* sym)
+ {
+ return m_instanceData->toKodi->HwGetProcAddress(m_instanceData->toKodi->kodiInstance, sym);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+//--==----==----==----==----==----==----==----==----==----==----==----==----==--
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_game_InputOperations 4. Input operations
+ /// @ingroup cpp_kodi_addon_game
+ /// @brief **Input operations**
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Hardware rendering operation parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_game_InputOperations_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_game_InputOperations_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Check if input is accepted for a feature on the controller
+ ///
+ /// If only a subset of the controller profile is used, this can return false
+ /// for unsupported features to not absorb their input.
+ ///
+ /// If the entire controller profile is used, this should always return true.
+ ///
+ /// @param[in] controller_id The ID of the controller profile
+ /// @param[in] feature_name The name of a feature in that profile
+ /// @return true if input is accepted for the feature, false otherwise
+ ///
+ virtual bool HasFeature(const std::string& controller_id, const std::string& feature_name)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the input topology that specifies which controllers can be connected
+ ///
+ /// @return The input topology, or null to use the default
+ ///
+ /// If this returns non-null, topology must be freed using FreeTopology().
+ ///
+ /// If this returns null, the topology will default to a single port that can
+ /// accept all controllers imported by addon.xml. The port ID is set to
+ /// the @ref DEFAULT_PORT_ID constant.
+ ///
+ virtual game_input_topology* GetTopology()
+ {
+ return nullptr;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Free the topology's resources
+ ///
+ /// @param[in] topology The topology returned by GetTopology()
+ ///
+ virtual void FreeTopology(game_input_topology* topology)
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the layouts for known controllers
+ ///
+ /// @param[in] controllers The controller layouts
+ ///
+ /// After loading the input topology, the frontend will call this with
+ /// controller layouts for all controllers discovered in the topology.
+ ///
+ virtual void SetControllerLayouts(const std::vector<kodi::addon::GameControllerLayout>& controllers)
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Enable/disable keyboard input using the specified controller
+ ///
+ /// @param[in] enable True to enable input, false otherwise
+ /// @param[in] controller_id The controller ID if enabling, or unused if disabling
+ ///
+ /// @return True if keyboard input was enabled, false otherwise
+ ///
+ virtual bool EnableKeyboard(bool enable, const std::string& controller_id)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Enable/disable mouse input using the specified controller
+ ///
+ /// @param[in] enable True to enable input, false otherwise
+ /// @param[in] controller_id The controller ID if enabling, or unused if disabling
+ ///
+ /// @return True if mouse input was enabled, false otherwise
+ ///
+ virtual bool EnableMouse(bool enable, const std::string& controller_id)
+ {
+ return false;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Connect/disconnect a controller to a port on the virtual game console
+ ///
+ /// @param[in] connect True to connect a controller, false to disconnect
+ /// @param[in] port_address The address of the port
+ /// @param[in] controller_id The controller ID if connecting, or unused if disconnecting
+ /// @return True if the \p controller was (dis-)connected to the port, false otherwise
+ ///
+ /// The address is a string that allows traversal of the controller topology.
+ /// It is formed by alternating port IDs and controller IDs separated by "/".
+ ///
+ /// For example, assume that the topology represented in XML for Snes9x is:
+ ///
+ /// ~~~~~~~~~~~~~{.xml}
+ /// <logicaltopology>
+ /// <port type="controller" id="1">
+ /// <accepts controller="game.controller.snes"/>
+ /// <accepts controller="game.controller.snes.multitap">
+ /// <port type="controller" id="1">
+ /// <accepts controller="game.controller.snes"/>
+ /// </port>
+ /// <port type="controller" id="2">
+ /// <accepts controller="game.controller.snes"/>
+ /// </port>
+ /// ...
+ /// </accepts>
+ /// </port>
+ /// </logicaltopology>
+ /// ~~~~~~~~~~~~~
+ ///
+ /// To connect a multitap to the console's first port, the multitap's controller
+ /// info is set using the port address:
+ ///
+ /// 1
+ ///
+ /// To connect a SNES controller to the second port of the multitap, the
+ /// controller info is next set using the address:
+ ///
+ /// 1/game.controller.multitap/2
+ ///
+ /// Any attempts to connect a controller to a port on a disconnected multitap
+ /// will return false.
+ ///
+ virtual bool ConnectController(bool connect,
+ const std::string& port_address,
+ const std::string& controller_id)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify the add-on of an input event
+ ///
+ /// @param[in] event The input event
+ ///
+ /// @return true if the event was handled, false otherwise
+ ///
+ virtual bool InputEvent(const game_input_event& event)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**<br>Notify the port of an input event
+ ///
+ /// @param[in] event The input event
+ /// @return true if the event was handled, false otherwise
+ ///
+ /// @note Input events can arrive for the following sources:
+ /// - @ref GAME_INPUT_EVENT_MOTOR
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool KodiInputEvent(const game_input_event& event)
+ {
+ return m_instanceData->toKodi->InputEvent(m_instanceData->toKodi->kodiInstance, &event);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+//--==----==----==----==----==----==----==----==----==----==----==----==----==--
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_game_SerializationOperations 5. Serialization operations
+ /// @ingroup cpp_kodi_addon_game
+ /// @brief **Serialization operations**
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Serialization operation parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_game_SerializationOperations_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_game_SerializationOperations_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Get the number of bytes required to serialize the game
+ ///
+ /// @return the number of bytes, or 0 if serialization is not supported
+ ///
+ virtual size_t SerializeSize()
+ {
+ return 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Serialize the state of the game
+ ///
+ /// @param[in] data The buffer receiving the serialized game data
+ /// @param[in] size The size of the buffer
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was serialized into the buffer
+ ///
+ virtual GAME_ERROR Serialize(uint8_t* data, size_t size)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Deserialize the game from the given state
+ ///
+ /// @param[in] data A buffer containing the game's new state
+ /// @param[in] size The size of the buffer
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game deserialized
+ ///
+ virtual GAME_ERROR Deserialize(const uint8_t* data, size_t size)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+//--==----==----==----==----==----==----==----==----==----==----==----==----==--
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_game_CheatOperations 6. Cheat operations
+ /// @ingroup cpp_kodi_addon_game
+ /// @brief **Cheat operations**
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Cheat operation parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_game_CheatOperations_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_game_CheatOperations_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Reset the cheat system
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the cheat system was reset
+ ///
+ virtual GAME_ERROR CheatReset()
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get a region of memory
+ ///
+ /// @param[in] type The type of memory to retrieve
+ /// @param[in] data Set to the region of memory; must remain valid until UnloadGame() is called
+ /// @param[in] size Set to the size of the region of memory
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if data was set to a valid buffer
+ ///
+ virtual GAME_ERROR GetMemory(GAME_MEMORY type, uint8_t*& data, size_t& size)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set a cheat code
+ ///
+ /// @param[in] index
+ /// @param[in] enabled
+ /// @param[in] code
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the cheat was set
+ ///
+ virtual GAME_ERROR SetCheat(unsigned int index, bool enabled, const std::string& code)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief Generates a RetroAchievements hash for a given game that
+ /// can be used to identify the game by RetroAchievements
+ ///
+ /// @param[out] hash The hash of the file. Its size must be >=33 characters
+ /// @param[in] consoleID The console ID as it is defined by rcheevos for
+ /// the console the ROM is made for
+ /// @param[in] filePath The path of the rom
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the hash was generated
+ /// successfully
+ ///
+ virtual GAME_ERROR RCGenerateHashFromFile(std::string& hash,
+ unsigned int consoleID,
+ const std::string& filePath)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief Gets a URL to the endpoint that returns the game ID
+ ///
+ /// @param[out] url The URL to GET the game ID
+ /// @param[in] size The size of the URL char array
+ /// @param[in] hash The hash of the rom
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the URL was created
+ ///
+ virtual GAME_ERROR RCGetGameIDUrl(std::string& url, const std::string& hash)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief Gets a URL to the endpoint that returns the patch file
+ ///
+ /// @param[out] url The URL to GET the game patch file
+ /// @param[in] size The size of the URL char array
+ /// @param[in] username The RetroAchievements username of the user
+ /// @param[in] token The login token to RetroAchievements of the user
+ /// @param[in] gameID The ID of the game in RetroAchievements API
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the URL was created
+ ///
+ virtual GAME_ERROR RCGetPatchFileUrl(std::string& url,
+ const std::string& username,
+ const std::string& token,
+ unsigned int gameID)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief Gets a URL to the endpoint that updates the rich presence
+ /// in the user's RetroAchievements profile
+ ///
+ /// @param[out] url The URL to POST the rich presence to RetroAchievements
+ /// @param[in] urlSize The size of the URL char array
+ /// @param[out] postData The post data of the request
+ /// @param[in] postSize The size of the post data char array
+ /// @param[in] username The RetroAchievements username of the user
+ /// @param[in] token The login token to RetroAchievements of the user
+ /// @param[in] gameID The ID of the game in RetroAchievements API
+ /// @param[in] richPresence The rich presence evaluation to POST
+ ///
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the URL and post data
+ /// were created
+ ///
+ virtual GAME_ERROR RCPostRichPresenceUrl(std::string& url,
+ std::string& postData,
+ const std::string& username,
+ const std::string& token,
+ unsigned int gameID,
+ const std::string& richPresence)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief Enables rich presence
+ ///
+ /// @param[in] script The rich presence script from RetroAchievements
+ ///
+ /// @return the error, or GAME_ERROR_NO_ERROR if rich presence was enabled
+ ///
+ virtual GAME_ERROR RCEnableRichPresence(const std::string& script)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief Gets the rich presence evaluation for the current frame.
+ /// Rich presence must be enabled first or this will fail.
+ ///
+ /// @param[out] evaluation The evaluation of what the player is doing in
+ /// the game this frame
+ /// @param[in] size The size of the evaluation char pointer
+ /// @param[in] consoleID The console ID as it is defined by rcheevos for
+ /// the console the rom is made for
+ /// @return the error, or @ref GAME_ERROR_NO_ERROR if the evaluation was
+ /// created successfully
+ ///
+ virtual GAME_ERROR RCGetRichPresenceEvaluation(std::string& evaluation, unsigned int consoleID)
+ {
+ return GAME_ERROR_NOT_IMPLEMENTED;
+ }
+
+ //============================================================================
+ /// @brief Resets the runtime. Must be called each time a new rom is starting
+ /// and when the savestate is changed
+ ///
+ /// @return the error, or GAME_ERROR_NO_ERROR if the runtim was reseted
+ /// successfully
+ ///
+ virtual GAME_ERROR RCResetRuntime() { return GAME_ERROR_NOT_IMPLEMENTED; }
+
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+
+ instance->game->toAddon->LoadGame = ADDON_LoadGame;
+ instance->game->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial;
+ instance->game->toAddon->LoadStandalone = ADDON_LoadStandalone;
+ instance->game->toAddon->UnloadGame = ADDON_UnloadGame;
+ instance->game->toAddon->GetGameTiming = ADDON_GetGameTiming;
+ instance->game->toAddon->GetRegion = ADDON_GetRegion;
+ instance->game->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop;
+ instance->game->toAddon->RunFrame = ADDON_RunFrame;
+ instance->game->toAddon->Reset = ADDON_Reset;
+
+ instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
+ instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
+
+ instance->game->toAddon->HasFeature = ADDON_HasFeature;
+ instance->game->toAddon->GetTopology = ADDON_GetTopology;
+ instance->game->toAddon->FreeTopology = ADDON_FreeTopology;
+ instance->game->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts;
+ instance->game->toAddon->EnableKeyboard = ADDON_EnableKeyboard;
+ instance->game->toAddon->EnableMouse = ADDON_EnableMouse;
+ instance->game->toAddon->ConnectController = ADDON_ConnectController;
+ instance->game->toAddon->InputEvent = ADDON_InputEvent;
+
+ instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
+ instance->game->toAddon->Serialize = ADDON_Serialize;
+ instance->game->toAddon->Deserialize = ADDON_Deserialize;
+
+ instance->game->toAddon->CheatReset = ADDON_CheatReset;
+ instance->game->toAddon->GetMemory = ADDON_GetMemory;
+ instance->game->toAddon->SetCheat = ADDON_SetCheat;
+
+ instance->game->toAddon->RCGenerateHashFromFile = ADDON_RCGenerateHashFromFile;
+ instance->game->toAddon->RCGetGameIDUrl = ADDON_RCGetGameIDUrl;
+ instance->game->toAddon->RCGetPatchFileUrl = ADDON_RCGetPatchFileUrl;
+ instance->game->toAddon->RCPostRichPresenceUrl = ADDON_RCPostRichPresenceUrl;
+ instance->game->toAddon->RCEnableRichPresence = ADDON_RCEnableRichPresence;
+ instance->game->toAddon->RCGetRichPresenceEvaluation = ADDON_RCGetRichPresenceEvaluation;
+ instance->game->toAddon->RCResetRuntime = ADDON_RCResetRuntime;
+
+ instance->game->toAddon->FreeString = ADDON_FreeString;
+
+ m_instanceData = instance->game;
+ m_instanceData->toAddon->addonInstance = this;
+ }
+
+ // --- Game operations ---------------------------------------------------------
+
+ inline static GAME_ERROR ADDON_LoadGame(const AddonInstance_Game* instance, const char* url)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadGame(url);
+ }
+
+ inline static GAME_ERROR ADDON_LoadGameSpecial(const AddonInstance_Game* instance,
+ SPECIAL_GAME_TYPE type,
+ const char** urls,
+ size_t urlCount)
+ {
+ std::vector<std::string> urlList;
+ for (size_t i = 0; i < urlCount; ++i)
+ {
+ if (urls[i] != nullptr)
+ urlList.push_back(urls[i]);
+ }
+
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->LoadGameSpecial(type, urlList);
+ }
+
+ inline static GAME_ERROR ADDON_LoadStandalone(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadStandalone();
+ }
+
+ inline static GAME_ERROR ADDON_UnloadGame(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->UnloadGame();
+ }
+
+ inline static GAME_ERROR ADDON_GetGameTiming(const AddonInstance_Game* instance,
+ game_system_timing* timing_info)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->GetGameTiming(*timing_info);
+ }
+
+ inline static GAME_REGION ADDON_GetRegion(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetRegion();
+ }
+
+ inline static bool ADDON_RequiresGameLoop(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RequiresGameLoop();
+ }
+
+ inline static GAME_ERROR ADDON_RunFrame(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RunFrame();
+ }
+
+ inline static GAME_ERROR ADDON_Reset(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Reset();
+ }
+
+
+ // --- Hardware rendering operations -------------------------------------------
+
+ inline static GAME_ERROR ADDON_HwContextReset(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextReset();
+ }
+
+ inline static GAME_ERROR ADDON_HwContextDestroy(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextDestroy();
+ }
+
+
+ // --- Input operations --------------------------------------------------------
+
+ inline static bool ADDON_HasFeature(const AddonInstance_Game* instance,
+ const char* controller_id,
+ const char* feature_name)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->HasFeature(controller_id, feature_name);
+ }
+
+ inline static game_input_topology* ADDON_GetTopology(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetTopology();
+ }
+
+ inline static void ADDON_FreeTopology(const AddonInstance_Game* instance,
+ game_input_topology* topology)
+ {
+ static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->FreeTopology(topology);
+ }
+
+ inline static void ADDON_SetControllerLayouts(const AddonInstance_Game* instance,
+ const game_controller_layout* controllers,
+ unsigned int controller_count)
+ {
+ if (controllers == nullptr)
+ return;
+
+ std::vector<GameControllerLayout> controllerList;
+ for (unsigned int i = 0; i < controller_count; ++i)
+ controllerList.push_back(controllers[i]);
+
+ static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->SetControllerLayouts(controllerList);
+ }
+
+ inline static bool ADDON_EnableKeyboard(const AddonInstance_Game* instance,
+ bool enable,
+ const char* controller_id)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->EnableKeyboard(enable, controller_id);
+ }
+
+ inline static bool ADDON_EnableMouse(const AddonInstance_Game* instance,
+ bool enable,
+ const char* controller_id)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->EnableMouse(enable, controller_id);
+ }
+
+ inline static bool ADDON_ConnectController(const AddonInstance_Game* instance,
+ bool connect,
+ const char* port_address,
+ const char* controller_id)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->ConnectController(connect, port_address, controller_id);
+ }
+
+ inline static bool ADDON_InputEvent(const AddonInstance_Game* instance,
+ const game_input_event* event)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->InputEvent(*event);
+ }
+
+
+ // --- Serialization operations ------------------------------------------------
+
+ inline static size_t ADDON_SerializeSize(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->SerializeSize();
+ }
+
+ inline static GAME_ERROR ADDON_Serialize(const AddonInstance_Game* instance,
+ uint8_t* data,
+ size_t size)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Serialize(data, size);
+ }
+
+ inline static GAME_ERROR ADDON_Deserialize(const AddonInstance_Game* instance,
+ const uint8_t* data,
+ size_t size)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Deserialize(data, size);
+ }
+
+
+ // --- Cheat operations --------------------------------------------------------
+
+ inline static GAME_ERROR ADDON_CheatReset(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->CheatReset();
+ }
+
+ inline static GAME_ERROR ADDON_GetMemory(const AddonInstance_Game* instance,
+ GAME_MEMORY type,
+ uint8_t** data,
+ size_t* size)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->GetMemory(type, *data, *size);
+ }
+
+ inline static GAME_ERROR ADDON_SetCheat(const AddonInstance_Game* instance,
+ unsigned int index,
+ bool enabled,
+ const char* code)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->SetCheat(index, enabled, code);
+ }
+
+ inline static GAME_ERROR ADDON_RCGenerateHashFromFile(const AddonInstance_Game* instance,
+ char** hash,
+ unsigned int consoleID,
+ const char* filePath)
+ {
+ std::string cppHash;
+
+ GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
+ if (!cppHash.empty() && hash)
+ {
+ *hash = new char[cppHash.size() + 1];
+ std::copy(cppHash.begin(), cppHash.end(), *hash);
+ (*hash)[cppHash.size()] = '\0';
+ }
+ return ret;
+ }
+
+ inline static GAME_ERROR ADDON_RCGetGameIDUrl(const AddonInstance_Game* instance,
+ char** url,
+ const char* hash)
+ {
+ std::string cppUrl;
+ GAME_ERROR ret =
+ static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
+ if (!cppUrl.empty() && url)
+ {
+ *url = new char[cppUrl.size() + 1];
+ std::copy(cppUrl.begin(), cppUrl.end(), *url);
+ (*url)[cppUrl.size()] = '\0';
+ }
+ return ret;
+ }
+
+ inline static GAME_ERROR ADDON_RCGetPatchFileUrl(const AddonInstance_Game* instance,
+ char** url,
+ const char* username,
+ const char* token,
+ unsigned int gameID)
+ {
+ std::string cppUrl;
+
+ GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
+ if (!cppUrl.empty() && url)
+ {
+ *url = new char[cppUrl.size() + 1];
+ std::copy(cppUrl.begin(), cppUrl.end(), *url);
+ (*url)[cppUrl.size()] = '\0';
+ }
+ return ret;
+ }
+
+ inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(const AddonInstance_Game* instance,
+ char** url,
+ char** postData,
+ const char* username,
+ const char* token,
+ unsigned int gameID,
+ const char* richPresence)
+ {
+ std::string cppUrl;
+ std::string cppPostData;
+ GAME_ERROR ret =
+ static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
+ if (!cppUrl.empty())
+ {
+ *url = new char[cppUrl.size() + 1];
+ std::copy(cppUrl.begin(), cppUrl.end(), *url);
+ (*url)[cppUrl.size()] = '\0';
+ }
+ if (!cppPostData.empty())
+ {
+ *postData = new char[cppPostData.size() + 1];
+ std::copy(cppPostData.begin(), cppPostData.end(), *postData);
+ (*postData)[cppPostData.size()] = '\0';
+ }
+
+ return ret;
+ }
+
+ inline static GAME_ERROR ADDON_RCEnableRichPresence(const AddonInstance_Game* instance,
+ const char* script)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->RCEnableRichPresence(script);
+ }
+
+ inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(const AddonInstance_Game* instance,
+ char** evaluation,
+ unsigned int consoleID)
+ {
+ std::string cppEvaluation;
+ GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
+ if (!cppEvaluation.empty())
+ {
+ *evaluation = new char[cppEvaluation.size() + 1];
+ std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
+ (*evaluation)[cppEvaluation.size()] = '\0';
+ }
+
+ return ret;
+ }
+
+ inline static GAME_ERROR ADDON_RCResetRuntime(const AddonInstance_Game* instance)
+ {
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCResetRuntime();
+ }
+
+ inline static void ADDON_FreeString(const AddonInstance_Game* instance, char* str)
+ {
+ delete[] str;
+ }
+
+ AddonInstance_Game* m_instanceData;
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/ImageDecoder.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/ImageDecoder.h
new file mode 100644
index 0000000..eb98f90
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/ImageDecoder.h
@@ -0,0 +1,711 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/addon-instance/imagedecoder.h"
+
+#ifdef __cplusplus
+
+#include <stdexcept>
+
+namespace kodi
+{
+namespace addon
+{
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_imagedecoder_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_imagedecoder
+/// @brief **Image decoder add-on general variables**
+///
+/// Used to exchange the available options between Kodi and addon.
+///
+///
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_imagedecoder_Defs_ImageDecoderInfoTag class ImageDecoderInfoTag
+/// @ingroup cpp_kodi_addon_imagedecoder_Defs
+/// @brief **Info tag data structure**\n
+/// Representation of available information of processed audio file.
+///
+/// This is used to get all the necessary data of audio stream and to have on
+/// created files by encoders.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_imagedecoder_Defs_ImageDecoderInfoTag_Help
+///
+///@{
+class ATTR_DLL_LOCAL ImageDecoderInfoTag
+{
+public:
+ /*! \cond PRIVATE */
+ ImageDecoderInfoTag() = default;
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ImageDecoderInfoTag_Help Value Help
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs_ImageDecoderInfoTag
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_imagedecoder_Defs_ImageDecoderInfoTag :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Width** | `int` | @ref ImageDecoderInfoTag::SetWidth "SetWidth" | @ref ImageDecoderInfoTag::GetWidth "GetWidth"
+ /// | **Height** | `int` | @ref ImageDecoderInfoTag::SetHeight "SetHeight" | @ref ImageDecoderInfoTag::GetHeight "GetHeight"
+ /// | **Distance** | `float` | @ref ImageDecoderInfoTag::SetDistance "SetDistance" | @ref ImageDecoderInfoTag::GetDistance "GetDistance"
+ /// | **Color** | @ref cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_COLOR | @ref ImageDecoderInfoTag::SetColor "SetColor" | @ref ImageDecoderInfoTag::GetColor "GetColor"
+ /// | **Orientation** | @ref cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_ORIENTATION | @ref ImageDecoderInfoTag::SetOrientation "SetOrientation" | @ref ImageDecoderInfoTag::GetOrientation "GetOrientation"
+ /// | **Metering mode** | @ref cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_METERING_MODE | @ref ImageDecoderInfoTag::SetMeteringMode "SetMeteringMode" | @ref ImageDecoderInfoTag::GetMeteringMode "GetMeteringMode"
+ /// | **Exposure time** | `float` | @ref ImageDecoderInfoTag::SetExposureTime "SetExposureTime" | @ref ImageDecoderInfoTag::GetExposureTime "GetExposureTime"
+ /// | **Exposure bias** | `float` | @ref ImageDecoderInfoTag::SetExposureBias "SetExposureBias" | @ref ImageDecoderInfoTag::GetExposureBias "GetExposureBias"
+ /// | **Exposure program** | @ref cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_EXPOSURE_PROGRAM | @ref ImageDecoderInfoTag::SetExposureProgram "SetExposureProgram" | @ref ImageDecoderInfoTag::GetExposureProgram "GetExposureProgram"
+ /// | **Exposure mode** | @ref cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_EXPOSURE_MODE | @ref ImageDecoderInfoTag::SetExposureMode "SetExposureMode" | @ref ImageDecoderInfoTag::GetExposureMode "GetExposureMode"
+ /// | **Time created** | `time_t` | @ref ImageDecoderInfoTag::SetTimeCreated "SetTimeCreated" | @ref ImageDecoderInfoTag::GetTimeCreated "GetTimeCreated"
+ /// | **Aperture F number** | `float` | @ref ImageDecoderInfoTag::SetApertureFNumber "SetApertureFNumber" | @ref ImageDecoderInfoTag::GetApertureFNumber "GetApertureFNumber"
+ /// | **Flash used** | @ref ADDON_IMG_FLASH_TYPE | @ref ImageDecoderInfoTag::SetFlashUsed "SetFlashUsed" | @ref ImageDecoderInfoTag::GetFlashUsed "GetFlashUsed"
+ /// | **Light source** | @ref ADDON_IMG_LIGHT_SOURCE | @ref ImageDecoderInfoTag::SetLightSource "SetLightSource" | @ref ImageDecoderInfoTag::GetLightSource "GetLightSource"
+ /// | **Focal length** | `int` | @ref ImageDecoderInfoTag::SetFocalLength "SetFocalLength" | @ref ImageDecoderInfoTag::GetFocalLength "GetFocalLength"
+ /// | **Focal length in 35 mm format** | `int` | @ref ImageDecoderInfoTag::SetFocalLengthIn35mmFormat "SetFocalLengthIn35mmFormat" | @ref ImageDecoderInfoTag::GetFocalLengthIn35mmFormat "GetFocalLengthIn35mmFormat"
+ /// | **Digital zoom ratio** | `float` | @ref ImageDecoderInfoTag::SetDigitalZoomRatio "SetDigitalZoomRatio" | @ref ImageDecoderInfoTag::GetDigitalZoomRatio "GetDigitalZoomRatio"
+ /// | **ISO sensitivity** | `float` | @ref ImageDecoderInfoTag::SetISOSpeed "SetISOSpeed" | @ref ImageDecoderInfoTag::GetISOSpeed "GetISOSpeed"
+ /// | **Camera manufacturer** | `std::string` | @ref ImageDecoderInfoTag::SetCameraManufacturer "SetCameraManufacturer" | @ref ImageDecoderInfoTag::GetCameraManufacturer "GetCameraManufacturer"
+ /// | **GPS info** | `bool, char, float[3], char, float[3], int, float` | @ref ImageDecoderInfoTag::SetGPSInfo "SetGPSInfo" | @ref ImageDecoderInfoTag::GetGPSInfo "GetGPSInfo"
+ /// | **Camera model** | `std::string` | @ref ImageDecoderInfoTag::SetCameraModel "SetCameraModel" | @ref ImageDecoderInfoTag::GetCameraModel "GetCameraModel"
+ /// | **Author** | `std::string` | @ref ImageDecoderInfoTag::SetAuthor "SetAuthor" | @ref ImageDecoderInfoTag::GetAuthor "GetAuthor"
+ /// | **Description** | `std::string` | @ref ImageDecoderInfoTag::SetDescription "SetDescription" | @ref ImageDecoderInfoTag::GetDescription "GetDescription"
+ /// | **Copyright** | `std::string` | @ref ImageDecoderInfoTag::SetCopyright "SetCopyright" | @ref ImageDecoderInfoTag::GetCopyright "GetCopyright"
+
+ /// @addtogroup cpp_kodi_addon_imagedecoder_Defs_ImageDecoderInfoTag
+ ///@{
+
+ /// @brief Set the camera manufacturer as string on info tag.
+ void SetWidth(int width) { m_width = width; }
+
+ /// @brief Get image width as pixels
+ int GetWidth() const { return m_width; }
+
+ /// @brief Set the image height as pixels.
+ void SetHeight(int height) { m_height = height; }
+
+ /// @brief Get image height as pixels.
+ int GetHeight() const { return m_height; }
+
+ /// @brief Set the image distance in meters.
+ void SetDistance(int distance) { m_distance = distance; }
+
+ /// @brief Get mage distance in meters.
+ int GetDistance() const { return m_distance; }
+
+ /// @brief Set the image color type.
+ ///
+ /// @copydetails cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_COLOR
+ void SetColor(ADDON_IMG_COLOR color) { m_color = color; }
+
+ /// @brief Get image image color type.
+ ADDON_IMG_COLOR GetColor() const { return m_color; }
+
+ /// @brief Set metering mode.
+ ///
+ /// @copydetails cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_METERING_MODE
+ void SetMeteringMode(ADDON_IMG_METERING_MODE metering_mode) { m_metering_mode = metering_mode; }
+
+ /// @brief Get metering mode.
+ ADDON_IMG_METERING_MODE GetMeteringMode() const { return m_metering_mode; }
+
+ /// @brief Set exposure time.
+ void SetExposureTime(float exposure_time) { m_exposure_time = exposure_time; }
+
+ /// @brief Get exposure time.
+ float GetExposureTime() const { return m_exposure_time; }
+
+ /// @brief Set exposure bias.
+ void SetExposureBias(float exposure_bias) { m_exposure_bias = exposure_bias; }
+
+ /// @brief Get exposure bias.
+ float GetExposureBias() const { return m_exposure_bias; }
+
+ /// @brief Set Exposure program.
+ ///
+ /// @copydetails cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_EXPOSURE_PROGRAM
+ void SetExposureProgram(ADDON_IMG_EXPOSURE_PROGRAM exposure_program)
+ {
+ m_exposure_program = exposure_program;
+ }
+
+ /// @brief Get Exposure program.
+ ADDON_IMG_EXPOSURE_PROGRAM GetExposureProgram() const { return m_exposure_program; }
+
+ /// @brief Set Exposure mode.
+ ///
+ /// @copydetails cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_EXPOSURE_MODE
+ void SetExposureMode(ADDON_IMG_EXPOSURE_MODE exposure_mode) { m_exposure_mode = exposure_mode; }
+
+ /// @brief Get Exposure mode.
+ ADDON_IMG_EXPOSURE_MODE GetExposureMode() const { return m_exposure_mode; }
+
+ /// @brief Set the orientation.
+ ///
+ /// @copydetails cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_ORIENTATION
+ void SetOrientation(ADDON_IMG_ORIENTATION orientation) { m_orientation = orientation; }
+
+ /// @brief Get image orientation.
+ ADDON_IMG_ORIENTATION GetOrientation() const { return m_orientation; }
+
+ /// @brief Set the image creation time in time_t format (number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC).
+ void SetTimeCreated(time_t time_created) { m_time_created = time_created; }
+
+ /// @brief Get image creation time.
+ time_t GetTimeCreated() const { return m_time_created; }
+
+ /// @brief Set Aperture F number.
+ void SetApertureFNumber(float aperture_f_number) { m_aperture_f_number = aperture_f_number; }
+
+ /// @brief Get Aperture F number.
+ float GetApertureFNumber() const { return m_aperture_f_number; }
+
+ /// @brief Set to true if image was created with flash.
+ void SetFlashUsed(ADDON_IMG_FLASH_TYPE flash_used) { m_flash_used = flash_used; }
+
+ /// @brief Get info about image was created with flash.
+ ADDON_IMG_FLASH_TYPE GetFlashUsed() const { return m_flash_used; }
+
+ /// @brief Set focal length
+ void SetFocalLength(int focal_length) { m_focal_length = focal_length; }
+
+ /// @brief Get focal length
+ int GetFocalLength() const { return m_focal_length; }
+
+ /// @brief Set light source
+ void SetLightSource(ADDON_IMG_LIGHT_SOURCE light_source) { m_light_source = light_source; }
+
+ /// @brief Get light source
+ ADDON_IMG_LIGHT_SOURCE GetLightSource() const { return m_light_source; }
+
+ /// @brief Set focal length in 35 mm format.
+ ///
+ /// @note Same as FocalLengthIn35mmFilm in EXIF standard, tag 0xa405.
+ void SetFocalLengthIn35mmFormat(int focal_length_in_35mm_format)
+ {
+ m_focal_length_in_35mm_format = focal_length_in_35mm_format;
+ }
+
+ /// @brief Get focal length in 35 mm format.
+ int GetFocalLengthIn35mmFormat() const { return m_focal_length_in_35mm_format; }
+
+ /// @brief Set digital zoom ratio.
+ void SetDigitalZoomRatio(float digital_zoom_ratio) { m_digital_zoom_ratio = digital_zoom_ratio; }
+
+ /// @brief Get digital zoom ratio.
+ float GetDigitalZoomRatio() const { return m_digital_zoom_ratio; }
+
+ /// @brief Set ISO sensitivity.
+ void SetISOSpeed(float iso_speed) { m_iso_speed = iso_speed; }
+
+ /// @brief Get ISO sensitivity.
+ float GetISOSpeed() const { return m_iso_speed; }
+
+ /// @brief Set GPS position information.
+ void SetGPSInfo(bool gps_info_present,
+ char latitude_ref,
+ float latitude[3],
+ char longitude_ref,
+ float longitude[3],
+ int altitude_ref,
+ float altitude)
+ {
+ if (!latitude || !longitude)
+ return;
+
+ m_gps_info_present = gps_info_present;
+ if (gps_info_present)
+ {
+ m_latitude_ref = latitude_ref;
+ m_longitude_ref = longitude_ref;
+ for (int i = 0; i < 3; i++)
+ {
+ m_latitude[i] = latitude[i];
+ m_longitude[i] = longitude[i];
+ }
+ m_altitude_ref = altitude_ref;
+ m_altitude = altitude;
+ }
+ else
+ {
+ m_latitude_ref = 0.0f;
+ m_longitude_ref = 0.0f;
+ for (int i = 0; i < 3; i++)
+ latitude[i] = longitude[i] = 0.0f;
+ m_altitude_ref = 0;
+ m_altitude = 0.0f;
+ }
+ }
+
+ /// @brief Get GPS position information.
+ void GetGPSInfo(bool& gps_info_present,
+ char& latitude_ref,
+ float latitude[3],
+ char& longitude_ref,
+ float longitude[3],
+ int& altitude_ref,
+ float& altitude)
+ {
+ if (!latitude || !longitude)
+ return;
+
+ gps_info_present = m_gps_info_present;
+ if (m_gps_info_present)
+ {
+ latitude_ref = m_latitude_ref;
+ longitude_ref = m_longitude_ref;
+ for (int i = 0; i < 3; i++)
+ {
+ latitude[i] = m_latitude[i];
+ longitude[i] = m_longitude[i];
+ }
+ altitude_ref = m_altitude_ref;
+ altitude = m_altitude;
+ }
+ else
+ {
+ latitude_ref = ' ';
+ longitude_ref = ' ';
+ for (int i = 0; i < 3; i++)
+ latitude[i] = longitude[i] = 0.0f;
+ altitude_ref = 0;
+ altitude = 0.0f;
+ }
+ }
+
+ /// @brief Set the camera manufacturer as string on info tag.
+ void SetCameraManufacturer(const std::string& camera_manufacturer)
+ {
+ m_camera_manufacturer = camera_manufacturer;
+ }
+
+ /// @brief Get camera manufacturer
+ std::string GetCameraManufacturer() const { return m_camera_manufacturer; }
+
+ /// @brief Set camera model
+ void SetCameraModel(const std::string& camera_model) { m_camera_model = camera_model; }
+
+ /// @brief Get camera model
+ std::string GetCameraModel() const { return m_camera_model; }
+
+ /// @brief Set author
+ void SetAuthor(const std::string& author) { m_author = author; }
+
+ /// @brief Get author
+ std::string GetAuthor() const { return m_author; }
+
+ /// @brief Set description
+ void SetDescription(const std::string& description) { m_description = description; }
+
+ /// @brief Get description
+ std::string GetDescription() const { return m_description; }
+
+ /// @brief Set copyright
+ void SetCopyright(const std::string& copyright) { m_copyright = copyright; }
+
+ /// @brief Get copyright
+ std::string GetCopyright() const { return m_copyright; }
+
+ ///@}
+
+private:
+ int m_width{};
+ int m_height{};
+ float m_distance{};
+ ADDON_IMG_ORIENTATION m_orientation{ADDON_IMG_ORIENTATION_NONE};
+ ADDON_IMG_COLOR m_color{ADDON_IMG_COLOR_COLORED};
+ ADDON_IMG_METERING_MODE m_metering_mode{ADDON_IMG_METERING_MODE_UNKNOWN};
+ float m_exposure_time{};
+ float m_exposure_bias{};
+ ADDON_IMG_EXPOSURE_PROGRAM m_exposure_program{ADDON_IMG_EXPOSURE_PROGRAM_UNDEFINED};
+ ADDON_IMG_EXPOSURE_MODE m_exposure_mode{ADDON_IMG_EXPOSURE_MODE_AUTO};
+ time_t m_time_created{};
+ float m_aperture_f_number{};
+ ADDON_IMG_FLASH_TYPE m_flash_used{ADDON_IMG_FLASH_TYPE_NO_FLASH};
+ ADDON_IMG_LIGHT_SOURCE m_light_source{};
+ int m_focal_length{};
+ int m_focal_length_in_35mm_format{};
+ float m_digital_zoom_ratio{};
+ float m_iso_speed{};
+
+ bool m_gps_info_present{false};
+ char m_latitude_ref{' '};
+ float m_latitude[3]{}; /* Deg,min,sec */
+ char m_longitude_ref{' '};
+ float m_longitude[3]{}; /* Deg,min,sec */
+ int m_altitude_ref{};
+ float m_altitude{};
+
+ std::string m_camera_manufacturer;
+ std::string m_camera_model;
+ std::string m_author;
+ std::string m_description;
+ std::string m_copyright;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+///
+/// @addtogroup cpp_kodi_addon_imagedecoder
+/// @brief @cpp_class{ kodi::addon::CInstanceImageDecoder }
+/// **Image decoder add-on instance**\n
+/// This instance type is used to allow Kodi various additional image format
+/// types.
+///
+/// This usage can be requested under various conditions, by a Mimetype protocol
+/// defined in <b>`addon.xml`</b> or supported file extensions.
+///
+/// Include the header @ref ImageDecoder.h "#include <kodi/addon-instance/ImageDecoder.h>"
+/// to use this class.
+///
+/// ----------------------------------------------------------------------------
+///
+/// Here is an example of what the <b>`addon.xml.in`</b> would look like for an
+/// image decoder addon:
+///
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="imagedecoder.myspecialnamefor"
+/// version="1.0.0"
+/// name="My image decoder addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="kodi.imagedecoder"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@">
+/// <support>
+/// <mimetype name="image/mymimea">
+/// <extension>.imga</extension>
+/// <description>30100</description>
+/// <icon>resources/file_format_icon_a.png</icon>
+/// </mimetype>
+/// <mimetype name="image/mymimeb">
+/// <extension>.imgb</extension>
+/// <description>30101</description>
+/// <icon>resources/file_format_icon_b.png</icon>
+/// </mimetype>
+/// </support>
+/// </extension>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My image decoder addon summary</summary>
+/// <description lang="en_GB">My image decoder description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+/// ### Standard values that can be declared for processing in `addon.xml`.
+///
+/// These values are used by Kodi to identify associated images and file
+/// extensions and then to select the associated addon.
+///
+/// \table_start
+/// \table_h3{ Labels, Type, Description }
+/// \table_row3{ <b>`point`</b>,
+/// @anchor cpp_kodi_addon_imagedecoder_point
+/// string,
+/// The identification of the addon instance to image decoder is mandatory
+/// <b>`kodi.imagedecoder`</b>. In addition\, the instance declared in the
+/// first <b>`<support>`</b> is also the main type of addon.
+/// }
+/// \table_row3{ <b>`library_@PLATFORM@`</b>,
+/// @anchor cpp_kodi_addon_imagedecoder_library
+/// string,
+/// The runtime library used for the addon. This is usually declared by `cmake` and correctly displayed in the translated <b>`addon.xml`</b>.
+/// }
+/// \table_row3{ <b>`<support>...</support>`</b>,
+/// @anchor cpp_kodi_addon_imagedecoder_support
+/// XML group,
+/// Contains the formats supported by the addon.
+/// }
+/// \table_row3{ <b>`<mimetype name="image/mymimea">...</mimetype>`</b>,
+/// @anchor cpp_kodi_addon_imagedecoder_mimetype
+/// string / group,
+/// The from addon operated image [mimetypes](https://en.wikipedia.org/wiki/Media_type).\n
+/// Optional can be with `<description>` and `<icon>` additional info added where used for list views in Kodi.
+/// }
+/// \table_row3{ <b>`<mimetype ...><extension>...</extension></mimetype>`</b>,
+/// @anchor cpp_kodi_addon_imagedecoder_mimetype
+/// string,
+/// The file extensions / styles supported by this addon and relates to given mimetype before.\n
+/// @note Required to use about info support by @ref CInstanceImageDecoder::SupportsFile and @ref CInstanceImageDecoder::ReadTag!
+/// }
+/// \table_end
+///
+/// @remark For more detailed description of the <b>`addon.xml`</b>, see also https://kodi.wiki/view/Addon.xml.
+///
+///
+/// --------------------------------------------------------------------------
+///
+///
+/// **Example:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/ImageDecoder.h>
+///
+/// class ATTR_DLL_LOCAL CMyImageDecoder : public kodi::addon::CInstanceImageDecoder
+/// {
+/// public:
+/// CMyImageDecoder(const kodi::addon::IInstanceInfo& instance);
+///
+/// bool LoadImageFromMemory(const uint8_t* buffer,
+/// size_t bufSize,
+/// unsigned int& width,
+/// unsigned int& height) override;
+///
+/// bool Decode(uint8_t* pixels,
+/// unsigned int width,
+/// unsigned int height,
+/// unsigned int pitch,
+/// ADDON_IMG_FMT format) override;
+///
+/// ...
+/// };
+///
+/// CMyImageDecoder::CMyImageDecoder(const kodi::addon::IInstanceInfo& instance)
+/// : CInstanceImageDecoder(instance)
+/// {
+/// ...
+/// }
+///
+/// bool CMyImageDecoder::LoadImageFromMemory(const uint8_t* buffer,
+/// size_t bufSize,
+/// unsigned int& width,
+/// unsigned int& height)
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// bool CMyImageDecoder::Decode(uint8_t* pixels,
+/// unsigned int width,
+/// unsigned int height,
+/// unsigned int pitch,
+/// ADDON_IMG_FMT format) override;
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// //----------------------------------------------------------------------
+///
+/// class ATTR_DLL_LOCAL CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_IMAGEDECODER))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my image decoder instance");
+/// hdl = new CMyImageDecoder(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyImageDecoder` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+//------------------------------------------------------------------------------
+class ATTR_DLL_LOCAL CInstanceImageDecoder : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_imagedecoder
+ /// @brief Class constructor.
+ ///
+ /// @param[in] instance The from Kodi given instance given be add-on
+ /// CreateInstance call with instance id
+ /// @ref ADDON_INSTANCE_IMAGEDECODER.
+ ///
+ explicit CInstanceImageDecoder(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceImageDecoder: Creation of multiple together "
+ "with single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ ~CInstanceImageDecoder() override = default;
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_imagedecoder
+ /// @brief Checks addon support given file path.
+ ///
+ /// @param[in] filename The file to read
+ /// @return true if successfully done and supported, otherwise false
+ ///
+ /// @note Optional to add, as default becomes `true` used.
+ ///
+ virtual bool SupportsFile(const std::string& filename) { return true; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_imagedecoder
+ /// @brief Read tag of a file.
+ ///
+ /// @param[in] file File to read tag for
+ /// @param[out] tag Information tag about
+ /// @return True on success, false on failure
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_imagedecoder_Defs_ImageDecoderInfoTag_Help
+ ///
+ virtual bool ReadTag(const std::string& file, kodi::addon::ImageDecoderInfoTag& tag)
+ {
+ return false;
+ }
+ //--------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_imagedecoder
+ /// @brief Initialize an encoder.
+ ///
+ /// @param[in] mimetype The mimetype wanted from Kodi
+ /// @param[in] buffer The data to read from memory
+ /// @param[in] bufSize The buffer size
+ /// @param[in,out] width The optimal width of image on entry, obtained width
+ /// on return
+ /// @param[in,out] height The optimal height of image, actual obtained height
+ /// on return
+ /// @return true if successful done, false on error
+ ///
+ virtual bool LoadImageFromMemory(const std::string& mimetype,
+ const uint8_t* buffer,
+ size_t bufSize,
+ unsigned int& width,
+ unsigned int& height) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_imagedecoder
+ /// @brief Decode previously loaded image.
+ ///
+ /// @param[in] pixels Output buffer
+ /// @param[in] width Width of output image
+ /// @param[in] height Height of output image
+ /// @param[in] pitch Pitch of output image
+ /// @param[in] format Format of output image
+ /// @return true if successful done, false on error
+ ///
+ virtual bool Decode(uint8_t* pixels,
+ unsigned int width,
+ unsigned int height,
+ unsigned int pitch,
+ ADDON_IMG_FMT format) = 0;
+ //----------------------------------------------------------------------------
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+ instance->imagedecoder->toAddon->supports_file = ADDON_supports_file;
+ instance->imagedecoder->toAddon->read_tag = ADDON_read_tag;
+ instance->imagedecoder->toAddon->load_image_from_memory = ADDON_load_image_from_memory;
+ instance->imagedecoder->toAddon->decode = ADDON_decode;
+ }
+
+ inline static bool ADDON_supports_file(const KODI_ADDON_IMAGEDECODER_HDL hdl, const char* file)
+ {
+ return static_cast<CInstanceImageDecoder*>(hdl)->SupportsFile(file);
+ }
+
+ inline static bool ADDON_read_tag(const KODI_ADDON_IMAGEDECODER_HDL hdl,
+ const char* file,
+ struct KODI_ADDON_IMAGEDECODER_INFO_TAG* tag)
+ {
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable : 4996)
+#endif // _WIN32
+ kodi::addon::ImageDecoderInfoTag cppTag;
+ bool ret = static_cast<CInstanceImageDecoder*>(hdl)->ReadTag(file, cppTag);
+ if (ret)
+ {
+ tag->width = cppTag.GetWidth();
+ tag->height = cppTag.GetHeight();
+ tag->distance = cppTag.GetDistance();
+ tag->color = cppTag.GetColor();
+ tag->orientation = cppTag.GetOrientation();
+ tag->metering_mode = cppTag.GetMeteringMode();
+ tag->exposure_time = cppTag.GetExposureTime();
+ tag->exposure_bias = cppTag.GetExposureBias();
+ tag->exposure_mode = cppTag.GetExposureMode();
+ tag->exposure_program = cppTag.GetExposureProgram();
+ tag->time_created = cppTag.GetTimeCreated();
+ tag->aperture_f_number = cppTag.GetApertureFNumber();
+ tag->flash_used = cppTag.GetFlashUsed();
+ tag->light_source = cppTag.GetLightSource();
+ tag->focal_length = cppTag.GetFocalLength();
+ tag->focal_length_in_35mm_format = cppTag.GetFocalLengthIn35mmFormat();
+ tag->iso_speed = cppTag.GetISOSpeed();
+ tag->digital_zoom_ratio = cppTag.GetDigitalZoomRatio();
+ cppTag.GetGPSInfo(tag->gps_info_present, tag->latitude_ref, tag->latitude, tag->longitude_ref,
+ tag->longitude, tag->altitude_ref, tag->altitude);
+ tag->camera_manufacturer = strdup(cppTag.GetCameraManufacturer().c_str());
+ tag->camera_model = strdup(cppTag.GetCameraModel().c_str());
+ tag->author = strdup(cppTag.GetAuthor().c_str());
+ tag->description = strdup(cppTag.GetDescription().c_str());
+ tag->copyright = strdup(cppTag.GetCopyright().c_str());
+ }
+ return ret;
+#ifdef _WIN32
+#pragma warning(pop)
+#endif // _WIN32
+ }
+
+ inline static bool ADDON_load_image_from_memory(const KODI_ADDON_IMAGEDECODER_HDL hdl,
+ const char* mimetype,
+ const uint8_t* buffer,
+ size_t bufSize,
+ unsigned int* width,
+ unsigned int* height)
+ {
+ return static_cast<CInstanceImageDecoder*>(hdl)->LoadImageFromMemory(mimetype, buffer, bufSize,
+ *width, *height);
+ }
+
+ inline static bool ADDON_decode(const KODI_ADDON_IMAGEDECODER_HDL hdl,
+ uint8_t* pixels,
+ size_t pixels_size,
+ unsigned int width,
+ unsigned int height,
+ unsigned int pitch,
+ enum ADDON_IMG_FMT format)
+ {
+ return static_cast<CInstanceImageDecoder*>(hdl)->Decode(pixels, width, height, pitch, format);
+ }
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Inputstream.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Inputstream.h
new file mode 100644
index 0000000..0320074
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Inputstream.h
@@ -0,0 +1,2050 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/addon-instance/inputstream.h"
+#include "inputstream/StreamCodec.h"
+#include "inputstream/StreamConstants.h"
+#include "inputstream/StreamCrypto.h"
+#include "inputstream/TimingConstants.h"
+
+#ifdef __cplusplus
+
+#include <map>
+
+namespace kodi
+{
+namespace addon
+{
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Doxygen group set for the definitions
+//{{{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_inputstream
+/// @brief **Inputstream add-on instance definition values**\n
+/// All inputstream functions associated data structures.
+///
+/// Used to exchange the available options between Kodi and addon.\n
+/// The groups described here correspond to the groups of functions on inputstream
+/// instance class.
+///
+/// In addition, some of the things described here are also used on the
+/// @ref cpp_kodi_addon_videocodec "video codec" addon.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_inputstream_Defs_Interface 1. Interface
+/// @ingroup cpp_kodi_addon_inputstream_Defs
+/// @brief **Inputstream add-on general variables**\n
+/// Used to exchange the available options between Kodi and addon.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_inputstream_Defs_StreamConstants 2. Stream constants
+/// @ingroup cpp_kodi_addon_inputstream_Defs
+/// @brief **Used to exchange any additional data between the caller and processor.**\n
+/// This includes the standardized values, in addition, an addon can also use
+/// its own special uses to be exchanged in the same way.
+///
+/// These values can be used by other addons (e.g. video addon) or stream files
+/// to select the respective inputstream addon and to transfer additional values.
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+///
+/// This example use the @ref STREAM_PROPERTY_INPUTSTREAM on a <b>`*.strm`</b>
+/// file to select needed addon and a additional value where related to selected
+/// addon itself.
+///
+/// ~~~~~~~~~~~~
+/// #KODIPROP:inputstream=inputstream.adaptive
+/// #KODIPROP:inputstream.adaptive.manifest_type=mpd
+/// http://rdmedia.bbc.co.uk/dash/ondemand/testcard/1/client_manifest-events-multilang.mpd
+/// ~~~~~~~~~~~~
+///
+/// These are then given to Kodi and the respectively selected addon by means of
+/// his @ref kodi::addon::CInstanceInputStream::Open "Open" call
+/// in @ref kodi::addon::InputstreamProperty::GetProperties.
+///
+/// The largest possible amount of these <b>`#KODIPROP`</b> values is defined
+/// with @ref STREAM_MAX_PROPERTY_COUNT.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_inputstream_Defs_TimingConstants 3. Stream timing
+/// @ingroup cpp_kodi_addon_inputstream_Defs
+/// @brief **Timebase and timestamp definitions.**\n
+/// Used to exchange the available options between Kodi and addon.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_inputstream_Defs_StreamCodec 4. Stream codec
+/// @ingroup cpp_kodi_addon_inputstream_Defs
+/// @brief **Inputstream codec control**\n
+/// Used to manage stream codec data.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_inputstream_Defs_StreamEncryption 5. Stream encryption
+/// @ingroup cpp_kodi_addon_inputstream_Defs
+/// @brief **Inputstream encryption control**\n
+/// Used to manage encrypted streams within addon.
+///
+
+//}}}
+//______________________________________________________________________________
+
+class CInstanceInputStream;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs_InputstreamProperty class InputstreamProperty
+/// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+/// @brief <b>URL and Data of key/value pairs passed to addon on @ref kodi::addon::CInstanceInputStream::Open "Open".</b>\n
+/// This is used to have the necessary data of the stream to be opened.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_inputstream_Defs_InputstreamProperty_Help
+///
+/// @warning This data are only given from Kodi to addon and can't be used
+/// on other places on addon.
+///
+///@{
+class ATTR_DLL_LOCAL InputstreamProperty
+ : public CStructHdl<InputstreamProperty, INPUTSTREAM_PROPERTY>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceInputStream;
+ /*! \endcond */
+
+public:
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_InputstreamProperty_Help Value Help
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_InputstreamProperty
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_inputstream_Defs_InputstreamProperty :</b>
+ /// | Name | Type | Get call
+ /// |------|------|----------
+ /// | **Stream URL** | `std::string` | @ref InputstreamProperty::GetURL "GetURL"
+ /// | **Mime type** | `std::string` | @ref InputstreamProperty::GetMimeType "GetMimeType"
+ /// | **Available amount of properties** | `unsigned int` | @ref InputstreamProperty::GetPropertiesAmount "GetPropertiesAmount"
+ /// | **List of properties** | `std::map<std::string, std::string>` | @ref InputstreamProperty::GetProperties "GetProperties"
+ /// | **Get addon library folder** | `std::string` | @ref InputstreamProperty::GetLibFolder "GetLibFolder"
+ /// | **Get addon profile/user folder** | `std::string` | @ref InputstreamProperty::GetProfileFolder "GetProfileFolder"
+
+ /// @addtogroup cpp_kodi_addon_inputstream_Defs_InputstreamProperty
+ ///@{
+
+ /// @brief Stream URL to open.
+ std::string GetURL() const { return m_cStructure->m_strURL; }
+
+ /// @brief Stream mime type.
+ std::string GetMimeType() const { return m_cStructure->m_mimeType; }
+
+ /// @brief Amount of available properties.
+ unsigned int GetPropertiesAmount() const
+ {
+ return m_cStructure->m_nCountInfoValues;
+ }
+
+ /// @brief List of available properties-
+ const std::map<std::string, std::string> GetProperties() const
+ {
+ std::map<std::string, std::string> props;
+ for (unsigned int i = 0; i < m_cStructure->m_nCountInfoValues; ++i)
+ {
+ props.emplace(m_cStructure->m_ListItemProperties[i].m_strKey,
+ m_cStructure->m_ListItemProperties[i].m_strValue);
+ }
+ return props;
+ }
+
+ /// @brief Get addon library folder.
+ ///
+ /// @note As alternative can also @ref kodi::GetAddonPath used.
+ std::string GetLibFolder() const { return m_cStructure->m_libFolder; }
+
+ /// @brief Get addon profile/user folder.
+ ///
+ /// @note As alternative can also @ref kodi::GetBaseUserPath used.
+ std::string GetProfileFolder() const { return m_cStructure->m_profileFolder; }
+
+ ///@}
+
+private:
+ InputstreamProperty() = delete;
+ InputstreamProperty(const InputstreamProperty& stream) = delete;
+ InputstreamProperty(const INPUTSTREAM_PROPERTY* stream) : CStructHdl(stream) {}
+ InputstreamProperty(INPUTSTREAM_PROPERTY* stream) : CStructHdl(stream) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities class InputstreamCapabilities
+/// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+/// @brief **InputStream add-on capabilities. All capabilities are set to "false" as default.**\n
+/// Asked to addon on @ref kodi::addon::CInstanceInputStream::GetCapabilities "GetCapabilities".
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities_Help
+///
+///@{
+class ATTR_DLL_LOCAL InputstreamCapabilities
+ : public CStructHdl<InputstreamCapabilities, INPUTSTREAM_CAPABILITIES>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceInputStream;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ InputstreamCapabilities() = default;
+ InputstreamCapabilities(const InputstreamCapabilities& stream) : CStructHdl(stream) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities_Help Value Help
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Capabilities bit mask** | `uint32_t` | @ref InputstreamCapabilities::SetMask "SetMask" | @ref InputstreamCapabilities::GetMask "GetMask"
+
+ /// @addtogroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities
+ ///@{
+
+ /// @brief Set of supported capabilities.
+ void SetMask(uint32_t mask) const { m_cStructure->m_mask = mask; }
+
+ /// @brief Get of supported capabilities.
+ uint32_t GetMask() const { return m_cStructure->m_mask; }
+
+ ///@}
+
+private:
+ InputstreamCapabilities(const INPUTSTREAM_CAPABILITIES* stream) : CStructHdl(stream) {}
+ InputstreamCapabilities(INPUTSTREAM_CAPABILITIES* stream) : CStructHdl(stream) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata class InputstreamMasteringMetadata
+/// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+/// @brief **Mastering metadata.**\n
+/// Describes the metadata for [HDR10](https://en.wikipedia.org/wiki/High-dynamic-range_video).
+///
+/// Used when video is compressed using [High Efficiency Video Coding (HEVC)](https://en.wikipedia.org/wiki/High_Efficiency_Video_Coding).
+/// This is used to describe the capabilities of the display used to master the
+/// content and the luminance values of the content.
+///
+/// Used on @ref kodi::addon::InputstreamInfo::SetMasteringMetadata and @ref kodi::addon::InputstreamInfo::GetMasteringMetadata.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata_Help
+///
+///@{
+class ATTR_DLL_LOCAL InputstreamMasteringMetadata
+ : public CStructHdl<InputstreamMasteringMetadata, INPUTSTREAM_MASTERING_METADATA>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceInputStream;
+ friend class InputstreamInfo;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ InputstreamMasteringMetadata() = default;
+ InputstreamMasteringMetadata(const InputstreamMasteringMetadata& stream) : CStructHdl(stream) {}
+ InputstreamMasteringMetadata& operator=(const InputstreamMasteringMetadata&) = default;
+
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata_Help Value Help
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Chromaticity X coordinates of the red** | `double` | @ref InputstreamMasteringMetadata::SetPrimaryR_ChromaticityX "SetPrimaryR_ChromaticityX" | @ref InputstreamMasteringMetadata::GetPrimaryR_ChromaticityX "GetPrimaryR_ChromaticityX"
+ /// | **Chromaticity Y coordinates of the red** | `double` | @ref InputstreamMasteringMetadata::SetPrimaryR_ChromaticityY "SetPrimaryR_ChromaticityY" | @ref InputstreamMasteringMetadata::GetPrimaryR_ChromaticityY "GetPrimaryR_ChromaticityY"
+ /// | **Chromaticity X coordinates of the green** | `double` | @ref InputstreamMasteringMetadata::SetPrimaryG_ChromaticityX "SetPrimaryG_ChromaticityX" | @ref InputstreamMasteringMetadata::GetPrimaryG_ChromaticityX "GetPrimaryG_ChromaticityX"
+ /// | **Chromaticity Y coordinates of the green** | `double` | @ref InputstreamMasteringMetadata::SetPrimaryG_ChromaticityY "SetPrimaryG_ChromaticityY" | @ref InputstreamMasteringMetadata::GetPrimaryG_ChromaticityY "GetPrimaryG_ChromaticityY"
+ /// | **Chromaticity X coordinates of the blue** | `double` | @ref InputstreamMasteringMetadata::SetPrimaryB_ChromaticityX "SetPrimaryB_ChromaticityX" | @ref InputstreamMasteringMetadata::GetPrimaryB_ChromaticityX "GetPrimaryB_ChromaticityX"
+ /// | **Chromaticity Y coordinates of the blue** | `double` | @ref InputstreamMasteringMetadata::SetPrimaryB_ChromaticityY "SetPrimaryB_ChromaticityY" | @ref InputstreamMasteringMetadata::GetPrimaryB_ChromaticityY "GetPrimaryB_ChromaticityY"
+ /// | **Chromaticity X coordinates of the white point** | `double` | @ref InputstreamMasteringMetadata::SetWhitePoint_ChromaticityX "SetWhitePoint_ChromaticityX" | @ref InputstreamMasteringMetadata::GetWhitePoint_ChromaticityX "GetWhitePoint_ChromaticityX"
+ /// | **Chromaticity Y coordinates of the white point** | `double` | @ref InputstreamMasteringMetadata::SetWhitePoint_ChromaticityY "SetWhitePoint_ChromaticityY" | @ref InputstreamMasteringMetadata::GetWhitePoint_ChromaticityY "GetWhitePoint_ChromaticityY"
+ /// | **Maximum number of bits of the display** | `double` | @ref InputstreamMasteringMetadata::SetLuminanceMax "SetLuminanceMax" | @ref InputstreamMasteringMetadata::GetLuminanceMax "GetLuminanceMax"
+ /// | **Minimum number of bits of the display** | `double` | @ref InputstreamMasteringMetadata::SetLuminanceMin "SetLuminanceMin" | @ref InputstreamMasteringMetadata::GetLuminanceMin "GetLuminanceMin"
+
+ /// @addtogroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata
+ ///@{
+
+ /// @brief Metadata class compare.
+ ///
+ /// To compare the metadata with another one.
+ ///
+ /// @return true if they equal, false otherwise
+ bool operator==(const kodi::addon::InputstreamMasteringMetadata& right) const
+ {
+ if (memcmp(m_cStructure, right.m_cStructure, sizeof(INPUTSTREAM_MASTERING_METADATA)) == 0)
+ return true;
+ return false;
+ }
+
+ /// @brief Set the chromaticity coordinates of the red value in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// X coordinate. The values are normalized to 50,000.
+ void SetPrimaryR_ChromaticityX(double value) { m_cStructure->primary_r_chromaticity_x = value; }
+
+ /// @brief Get the chromaticity X coordinates of the red value.
+ double GetPrimaryR_ChromaticityX() { return m_cStructure->primary_r_chromaticity_x; }
+
+ /// @brief The chromaticity coordinates of the red value in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// Y coordinate. The values are normalized to 50,000.
+ void SetPrimaryR_ChromaticityY(double value) { m_cStructure->primary_r_chromaticity_y = value; }
+
+ /// @brief Get the chromaticity Y coordinates of the red value.
+ double GetPrimaryR_ChromaticityY() { return m_cStructure->primary_r_chromaticity_y; }
+
+ /// @brief Set the chromaticity coordinates of the green value in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// X coordinate. The values are normalized to 50,000.
+ void SetPrimaryG_ChromaticityX(double value) { m_cStructure->primary_g_chromaticity_x = value; }
+
+ /// @brief Get the chromaticity X coordinates of the green value.
+ double GetPrimaryG_ChromaticityX() { return m_cStructure->primary_g_chromaticity_x; }
+
+ /// @brief Set the chromaticity coordinates of the green value in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// Y coordinate. The values are normalized to 50,000.
+ void SetPrimaryG_ChromaticityY(double value) { m_cStructure->primary_g_chromaticity_y = value; }
+
+ /// @brief Get the chromaticity Y coordinates of the green value.
+ double GetPrimaryG_ChromaticityY() { return m_cStructure->primary_g_chromaticity_y; }
+
+ /// @brief The chromaticity coordinates of the blue value in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// X coordinate. The values are normalized to 50,000.
+ void SetPrimaryB_ChromaticityX(double value) { m_cStructure->primary_b_chromaticity_x = value; }
+
+ /// @brief Get the chromaticity X coordinates of the blue value.
+ double GetPrimaryB_ChromaticityX() { return m_cStructure->primary_b_chromaticity_x; }
+
+ /// @brief The chromaticity coordinates of the blue value in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// Y coordinate. The values are normalized to 50,000.
+ void SetPrimaryB_ChromaticityY(double value) { m_cStructure->primary_b_chromaticity_y = value; }
+
+ /// @brief Get the chromaticity Y coordinates of the blue value.
+ double GetPrimaryB_ChromaticityY() { return m_cStructure->primary_b_chromaticity_y; }
+
+ /// @brief Set the chromaticity coordinates of the white point in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// X coordinate. The values are normalized to 50,000.
+ void SetWhitePoint_ChromaticityX(double value)
+ {
+ m_cStructure->white_point_chromaticity_x = value;
+ }
+
+ /// @brief Get the chromaticity X coordinates of the white point
+ double GetWhitePoint_ChromaticityX() { return m_cStructure->white_point_chromaticity_x; }
+
+ /// @brief Set the chromaticity coordinates of the white point in the
+ /// [CIE1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space.
+ ///
+ /// Y coordinate. The values are normalized to 50,000.
+ void SetWhitePoint_ChromaticityY(double value)
+ {
+ m_cStructure->white_point_chromaticity_y = value;
+ }
+
+ /// @brief Get the chromaticity Y coordinates of the white point.
+ double GetWhitePoint_ChromaticityY() { return m_cStructure->white_point_chromaticity_y; }
+
+ /// @brief Set the maximum number of bits of the display used to master the content.
+ ///
+ /// Values are normalized to 10,000.
+ void SetLuminanceMax(double value) { m_cStructure->luminance_max = value; }
+
+ /// @brief Get the maximum number of bits of the display.
+ double GetLuminanceMax() { return m_cStructure->luminance_max; }
+
+ /// @brief Set the minimum number of bits of the display used to master the content.
+ ///
+ /// Values are normalized to 10,000.
+ void SetLuminanceMin(double value) { m_cStructure->luminance_min = value; }
+
+ /// @brief Get the minimum number of bits of the display.
+ double GetLuminanceMin() { return m_cStructure->luminance_min; }
+
+ ///@}
+
+private:
+ InputstreamMasteringMetadata(const INPUTSTREAM_MASTERING_METADATA* stream) : CStructHdl(stream) {}
+ InputstreamMasteringMetadata(INPUTSTREAM_MASTERING_METADATA* stream) : CStructHdl(stream) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamContentlightMetadata class InputstreamContentlightMetadata
+/// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+/// @brief **Contentlight metadata**\n
+/// Describes the metadata for [HDR10](https://en.wikipedia.org/wiki/High-dynamic-range_video).
+/// See also @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata "InputstreamMasteringMetadata".
+///
+/// Used on @ref kodi::addon::InputstreamInfo::SetContentLightMetadata and @ref kodi::addon::InputstreamInfo::GetContentLightMetadata.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_inputstream_Defs_Interface_InputstreamContentlightMetadata_Help
+///
+///@{
+class ATTR_DLL_LOCAL InputstreamContentlightMetadata
+ : public CStructHdl<InputstreamContentlightMetadata, INPUTSTREAM_CONTENTLIGHT_METADATA>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceInputStream;
+ friend class InputstreamInfo;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ InputstreamContentlightMetadata() = default;
+ InputstreamContentlightMetadata(const InputstreamContentlightMetadata& stream)
+ : CStructHdl(stream)
+ {
+ }
+ InputstreamContentlightMetadata& operator=(const InputstreamContentlightMetadata&) = default;
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamContentlightMetadata_Help Value Help
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamContentlightMetadata
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamContentlightMetadata :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Maximum content light level** | `double` | @ref InputstreamContentlightMetadata::SetMaxCll "SetMaxCll" | @ref InputstreamContentlightMetadata::GetMaxCll "GetMaxCll"
+ /// | **Maximum frame average light level** | `double` | @ref InputstreamContentlightMetadata::SetMaxFall "SetMaxFall" | @ref InputstreamContentlightMetadata::GetMaxFall "GetMaxFall"
+
+ /// @addtogroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamContentlightMetadata
+ ///@{
+
+ /// @brief Metadata class compare.
+ ///
+ /// To compare the metadata with another one.
+ ///
+ /// @return true if they equal, false otherwise
+ bool operator==(const kodi::addon::InputstreamContentlightMetadata& right) const
+ {
+ if (memcmp(m_cStructure, right.m_cStructure, sizeof(INPUTSTREAM_CONTENTLIGHT_METADATA)) == 0)
+ return true;
+ return false;
+ }
+
+ /// @brief Set the maximum content light level (MaxCLL).
+ ///
+ /// This is the bit value corresponding to the brightest pixel used anywhere
+ /// in the content.
+ void SetMaxCll(uint64_t value) { m_cStructure->max_cll = value; }
+
+ /// @brief Get the maximum content light level (MaxCLL).
+ uint64_t GetMaxCll() { return m_cStructure->max_cll; }
+
+ /// @brief Set the maximum frame average light level (MaxFALL).
+ ///
+ /// This is the bit value corresponding to the average luminance of the frame
+ /// which has the brightest average luminance anywhere in the content.
+ void SetMaxFall(uint64_t value) { m_cStructure->max_fall = value; }
+
+ /// @brief Get the maximum frame average light level (MaxFALL).
+ uint64_t GetMaxFall() { return m_cStructure->max_fall; }
+
+ ///@}
+
+private:
+ InputstreamContentlightMetadata(const INPUTSTREAM_CONTENTLIGHT_METADATA* stream)
+ : CStructHdl(stream)
+ {
+ }
+ InputstreamContentlightMetadata(INPUTSTREAM_CONTENTLIGHT_METADATA* stream) : CStructHdl(stream) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo class InputstreamInfo
+/// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+/// @brief **Inputstream add-on stream info**\n
+/// This is used to give Kodi the associated and necessary data for an open stream.
+///
+/// Used on @ref kodi::addon::CInstanceInputStream::GetStream().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo_Help
+///
+///@{
+class ATTR_DLL_LOCAL InputstreamInfo : public CStructHdl<InputstreamInfo, INPUTSTREAM_INFO>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceInputStream;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ InputstreamInfo() = default;
+ InputstreamInfo(const InputstreamInfo& stream) : CStructHdl(stream)
+ {
+ SetCryptoSession(stream.GetCryptoSession());
+ CopyExtraData();
+ }
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo_Help Value Help
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo :</b>
+ /// | Name | Type used | Required | Set call | Get call
+ /// |------|-----------|----------|----------|---------
+ /// | **Stream type** | all | yes | @ref InputstreamInfo::SetStreamType "SetStreamType" | @ref InputstreamInfo::GetStreamType "GetStreamType"
+ /// | **Feature flags** | all | yes | @ref InputstreamInfo::SetFeatures "SetFeatures" | @ref InputstreamInfo::GetFeatures "GetFeatures"
+ /// | **Flags** | all | yes | @ref InputstreamInfo::SetFlags "SetFlags" | @ref InputstreamInfo::GetFlags "GetFlags"
+ /// | **Name** | all | no | @ref InputstreamInfo::SetName "SetName" | @ref InputstreamInfo::GetName "GetName"
+ /// | **Codec name** | all | yes | @ref InputstreamInfo::SetCodecName "SetCodecName" | @ref InputstreamInfo::GetCodecName "GetCodecName"
+ /// | **Codec internal name** | all | no | @ref InputstreamInfo::SetCodecInternalName "SetCodecInternalName" | @ref InputstreamInfo::GetCodecInternalName "GetCodecInternalName"
+ /// | **Codec Profile** | all | no | @ref InputstreamInfo::SetCodecProfile "SetCodecProfile" | @ref InputstreamInfo::GetCodecProfile "GetCodecProfile"
+ /// | **Physical index** | all | yes | @ref InputstreamInfo::SetPhysicalIndex "SetPhysicalIndex" | @ref InputstreamInfo::GetPhysicalIndex "GetPhysicalIndex"
+ /// | **Extra data** | Subtitle / all | Type related required | @ref InputstreamInfo::SetExtraData "SetExtraData" | @ref InputstreamInfo::GetExtraData "GetExtraData"
+ /// | **RFC 5646 language code** | all | no | @ref InputstreamInfo::SetLanguage "SetLanguage" | @ref InputstreamInfo::GetLanguage "GetLanguage"
+ /// | **FPS scale** | Video | Type related required | @ref InputstreamInfo::SetFpsScale "SetFpsScale" | @ref InputstreamInfo::GetFpsScale "GetFpsScale"
+ /// | **FPS rate** | Video | Type related required | @ref InputstreamInfo::SetFpsRate "SetFpsRate" | @ref InputstreamInfo::GetFpsRate "GetFpsRate"
+ /// | **Height** | Video | Type related required | @ref InputstreamInfo::SetHeight "SetHeight" | @ref InputstreamInfo::GetHeight "GetHeight"
+ /// | **Width** | Video | Type related required | @ref InputstreamInfo::SetWidth "SetWidth" | @ref InputstreamInfo::GetWidth "GetWidth"
+ /// | **Aspect** | Video | Type related required | @ref InputstreamInfo::SetAspect "SetAspect" | @ref InputstreamInfo::GetAspect "GetAspect"
+ /// | **Channel quantity** | Audio | Type related required | @ref InputstreamInfo::SetChannels "SetChannels" | @ref InputstreamInfo::GetChannels "GetChannels"
+ /// | **Sample rate** | Audio | Type related required | @ref InputstreamInfo::SetSampleRate "SetSampleRate" | @ref InputstreamInfo::GetSampleRate "GetSampleRate"
+ /// | **Bit rate** | Audio | Type related required | @ref InputstreamInfo::SetBitRate "SetBitRate" | @ref InputstreamInfo::GetBitRate "GetBitRate"
+ /// | **Bits per sample** | Audio | Type related required | @ref InputstreamInfo::SetBitsPerSample "SetBitsPerSample" | @ref InputstreamInfo::GetBitsPerSample "GetBitsPerSample"
+ /// | **Block align** | | no | @ref InputstreamInfo::SetBlockAlign "SetBlockAlign" | @ref InputstreamInfo::GetBlockAlign "GetBlockAlign"
+ /// | **Crypto session info** | | no | @ref InputstreamInfo::SetCryptoSession "SetCryptoSession" | @ref InputstreamInfo::GetCryptoSession "GetCryptoSession"
+ /// | **Four CC code** | | no | @ref InputstreamInfo::SetCodecFourCC "SetCodecFourCC" | @ref InputstreamInfo::GetCodecFourCC "GetCodecFourCC"
+ /// | **Color space** | | no | @ref InputstreamInfo::SetColorSpace "SetColorSpace" | @ref InputstreamInfo::GetColorSpace "GetColorSpace"
+ /// | **Color range** | | no | @ref InputstreamInfo::SetColorRange "SetColorRange" | @ref InputstreamInfo::GetColorRange "GetColorRange"
+ /// | **Color primaries** | | no | @ref InputstreamInfo::SetColorPrimaries "SetColorPrimaries" | @ref InputstreamInfo::GetColorPrimaries "GetColorPrimaries"
+ /// | **Color transfer characteristic** | | no | @ref InputstreamInfo::SetColorTransferCharacteristic "SetColorTransferCharacteristic" | @ref InputstreamInfo::GetColorTransferCharacteristic "GetColorTransferCharacteristic"
+ /// | **Mastering metadata** | | no | @ref InputstreamInfo::SetMasteringMetadata "SetMasteringMetadata" | @ref InputstreamInfo::GetMasteringMetadata "GetMasteringMetadata"
+ /// | **Content light metadata** | | no | @ref InputstreamInfo::SetContentLightMetadata "SetContentLightMetadata" | @ref InputstreamInfo::GetContentLightMetadata "GetContentLightMetadata"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo
+ ///@{
+
+ /// @brief Set the wanted stream type.
+ ///
+ /// @param[in] streamType By @ref INPUTSTREAM_TYPE defined type
+ void SetStreamType(INPUTSTREAM_TYPE streamType) { m_cStructure->m_streamType = streamType; }
+
+ /// @brief To get with @ref SetStreamType changed values.
+ INPUTSTREAM_TYPE GetStreamType() const { return m_cStructure->m_streamType; }
+
+ /// @brief Set special supported feature flags of inputstream.
+ ///
+ /// @param[in] features By @ref INPUTSTREAM_CODEC_FEATURES defined type
+ void SetFeatures(uint32_t features) { m_cStructure->m_features = features; }
+
+ /// @brief To get with @ref SetFeatures changed values.
+ uint32_t GetFeatures() const { return m_cStructure->m_features; }
+
+ /// @brief Set supported flags of inputstream.
+ ///
+ /// @param[in] flags The on @ref INPUTSTREAM_FLAGS defined flags to set
+ void SetFlags(uint32_t flags) { m_cStructure->m_flags = flags; }
+
+ /// @brief To get with @ref SetFeatures changed values.
+ uint32_t GetFlags() const { return m_cStructure->m_flags; }
+
+ /// @brief (optional) Name of the stream, leave empty for default handling.
+ ///
+ /// @param[in] name Stream name
+ void SetName(const std::string& name)
+ {
+ strncpy(m_cStructure->m_name, name.c_str(), INPUTSTREAM_MAX_STRING_NAME_SIZE);
+ }
+
+ /// @brief To get with @ref SetName changed values.
+ std::string GetName() const { return m_cStructure->m_name; }
+
+ /// @brief (required) Name of codec according to ffmpeg.
+ ///
+ /// See https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c about
+ /// available names.
+ ///
+ /// @remark On @ref INPUTSTREAM_TYPE_TELETEXT, @ref INPUTSTREAM_TYPE_RDS, and
+ /// @ref INPUTSTREAM_TYPE_ID3 this can be ignored and leaved empty.
+ ///
+ /// @param[in] codeName Codec name
+ void SetCodecName(const std::string& codecName)
+ {
+ strncpy(m_cStructure->m_codecName, codecName.c_str(), INPUTSTREAM_MAX_STRING_CODEC_SIZE);
+ }
+
+ /// @brief To get with @ref SetCodecName changed values.
+ std::string GetCodecName() const { return m_cStructure->m_codecName; }
+
+ /// @brief (optional) Internal name of codec (selectionstream info).
+ ///
+ /// @param[in] codecName Internal codec name
+ void SetCodecInternalName(const std::string& codecName)
+ {
+ strncpy(m_cStructure->m_codecInternalName, codecName.c_str(),
+ INPUTSTREAM_MAX_STRING_CODEC_SIZE);
+ }
+
+ /// @brief To get with @ref SetCodecInternalName changed values.
+ std::string GetCodecInternalName() const { return m_cStructure->m_codecInternalName; }
+
+ /// @brief (optional) The profile of the codec.
+ ///
+ /// @param[in] codecProfile Values with @ref STREAMCODEC_PROFILE to use
+ void SetCodecProfile(STREAMCODEC_PROFILE codecProfile)
+ {
+ m_cStructure->m_codecProfile = codecProfile;
+ }
+
+ /// @brief To get with @ref SetCodecProfile changed values.
+ STREAMCODEC_PROFILE GetCodecProfile() const { return m_cStructure->m_codecProfile; }
+
+ /// @brief (required) Physical index.
+ ///
+ /// @param[in] id Index identifier
+ void SetPhysicalIndex(unsigned int id) { m_cStructure->m_pID = id; }
+
+ /// @brief To get with @ref SetPhysicalIndex changed values.
+ unsigned int GetPhysicalIndex() const { return m_cStructure->m_pID; }
+
+ /// @brief Additional data where can needed on streams.
+ ///
+ /// @param[in] extraData List with memory of extra data
+ void SetExtraData(const std::vector<uint8_t>& extraData)
+ {
+ m_extraData = extraData;
+ m_cStructure->m_ExtraData = m_extraData.data();
+ m_cStructure->m_ExtraSize = m_extraData.size();
+ }
+
+ /// @brief Additional data where can needed on streams.
+ ///
+ /// @param[in] extraData Pointer with memory of extra data
+ /// @param[in] extraSize Size to store
+ void SetExtraData(const uint8_t* extraData, size_t extraSize)
+ {
+ m_extraData.clear();
+ if (extraData && extraSize > 0)
+ {
+ for (size_t i = 0; i < extraSize; ++i)
+ m_extraData.emplace_back(extraData[i]);
+ }
+
+ m_cStructure->m_ExtraData = m_extraData.data();
+ m_cStructure->m_ExtraSize = m_extraData.size();
+ }
+
+ /// @brief To get with @ref SetExtraData changed values.
+ const std::vector<uint8_t>& GetExtraData() { return m_extraData; }
+
+ /// @brief To get size with @ref SetExtraData changed values.
+ size_t GetExtraDataSize() { return m_extraData.size(); }
+
+ /// @brief Compare extra data from outside with class
+ ///
+ /// @param[in] extraData Pointer with memory of extra data for compare
+ /// @param[in] extraSize Size to compare
+ /// @return true if they equal, false otherwise
+ bool CompareExtraData(const uint8_t* extraData, size_t extraSize) const
+ {
+ if (!extraData || m_extraData.size() != extraSize)
+ return false;
+ for (size_t i = 0; i < extraSize; ++i)
+ {
+ if (m_extraData[i] != extraData[i])
+ return false;
+ }
+ return true;
+ }
+
+ /// @brief Clear additional data.
+ void ClearExtraData()
+ {
+ m_extraData.clear();
+ m_cStructure->m_ExtraData = m_extraData.data();
+ m_cStructure->m_ExtraSize = m_extraData.size();
+ }
+
+ /// @brief RFC 5646 language code (empty string if undefined).
+ ///
+ /// @param[in] language The language to set
+ void SetLanguage(const std::string& language)
+ {
+ strncpy(m_cStructure->m_language, language.c_str(), INPUTSTREAM_MAX_STRING_LANGUAGE_SIZE);
+ }
+
+ /// @brief To get with @ref SetLanguage changed values.
+ std::string GetLanguage() const { return m_cStructure->m_language; }
+
+ /// @brief Scale of 1000 and a rate of 29970 will result in 29.97 fps.
+ ///
+ /// @param[in] fpsScale Scale rate
+ void SetFpsScale(unsigned int fpsScale) { m_cStructure->m_FpsScale = fpsScale; }
+
+ /// @brief To get with @ref SetFpsScale changed values.
+ unsigned int GetFpsScale() const { return m_cStructure->m_FpsScale; }
+
+ /// @brief Rate to use for stream.
+ ///
+ /// @param[in] fpsRate Rate to use
+ void SetFpsRate(unsigned int fpsRate) { m_cStructure->m_FpsRate = fpsRate; }
+
+ /// @brief To get with @ref SetFpsRate changed values.
+ unsigned int GetFpsRate() const { return m_cStructure->m_FpsRate; }
+
+ /// @brief Height of the stream reported by the demuxer.
+ ///
+ /// @param[in] height Height to use
+ void SetHeight(unsigned int height) { m_cStructure->m_Height = height; }
+
+ /// @brief To get with @ref SetHeight changed values.
+ unsigned int GetHeight() const { return m_cStructure->m_Height; }
+
+ /// @brief Width of the stream reported by the demuxer.
+ ///
+ /// @param[in] width Width to use
+ void SetWidth(unsigned int width) { m_cStructure->m_Width = width; }
+
+ /// @brief To get with @ref SetWidth changed values.
+ unsigned int GetWidth() const { return m_cStructure->m_Width; }
+
+ /// @brief Display aspect of stream.
+ ///
+ /// @param[in] aspect Aspect ratio to use
+ void SetAspect(float aspect) { m_cStructure->m_Aspect = aspect; }
+
+ /// @brief To get with @ref SetAspect changed values.
+ float GetAspect() const { return m_cStructure->m_Aspect; }
+
+ /// @brief (required) Amount of channels.
+ ///
+ /// @param[in] sampleRate Channels to use
+ void SetChannels(unsigned int channels) { m_cStructure->m_Channels = channels; }
+
+ /// @brief To get with @ref SetChannels changed values.
+ unsigned int GetChannels() const { return m_cStructure->m_Channels; }
+
+ /// @brief (required) Sample rate.
+ ///
+ /// @param[in] sampleRate Rate to use
+ void SetSampleRate(unsigned int sampleRate) { m_cStructure->m_SampleRate = sampleRate; }
+
+ /// @brief To get with @ref SetSampleRate changed values.
+ unsigned int GetSampleRate() const { return m_cStructure->m_SampleRate; }
+
+ /// @brief Bit rate.
+ ///
+ /// @param[in] bitRate Rate to use
+ void SetBitRate(unsigned int bitRate) { m_cStructure->m_BitRate = bitRate; }
+
+ /// @brief To get with @ref SetBitRate changed values.
+ unsigned int GetBitRate() const { return m_cStructure->m_BitRate; }
+
+ /// @brief (required) Bits per sample.
+ ///
+ /// @param[in] bitsPerSample Bits per sample to use
+ void SetBitsPerSample(unsigned int bitsPerSample)
+ {
+ m_cStructure->m_BitsPerSample = bitsPerSample;
+ }
+
+ /// @brief To get with @ref SetBitsPerSample changed values.
+ unsigned int GetBitsPerSample() const { return m_cStructure->m_BitsPerSample; }
+
+ /// @brief To set the necessary stream block alignment size.
+ ///
+ /// @param[in] blockAlign Block size in byte
+ void SetBlockAlign(unsigned int blockAlign) { m_cStructure->m_BlockAlign = blockAlign; }
+
+ /// @brief To get with @ref SetBlockAlign changed values.
+ unsigned int GetBlockAlign() const { return m_cStructure->m_BlockAlign; }
+
+ /// @brief To set stream crypto session information.
+ ///
+ /// @param[in] cryptoSession The with @ref cpp_kodi_addon_inputstream_Defs_Interface_StreamCryptoSession setable info
+ ///
+ void SetCryptoSession(const kodi::addon::StreamCryptoSession& cryptoSession)
+ {
+ m_cryptoSession = cryptoSession;
+ memcpy(&m_cStructure->m_cryptoSession, m_cryptoSession.GetCStructure(),
+ sizeof(STREAM_CRYPTO_SESSION));
+ }
+
+ /// @brief To get with @ref GetCryptoSession changed values.
+ const kodi::addon::StreamCryptoSession& GetCryptoSession() const { return m_cryptoSession; }
+
+ /// @brief Codec If available, the fourcc code codec.
+ ///
+ /// @param[in] codecFourCC Codec four CC code
+ void SetCodecFourCC(unsigned int codecFourCC) { m_cStructure->m_codecFourCC = codecFourCC; }
+
+ /// @brief To get with @ref SetCodecFourCC changed values
+ unsigned int GetCodecFourCC() const { return m_cStructure->m_codecFourCC; }
+
+ /// @brief Definition of colorspace.
+ ///
+ /// @param[in] colorSpace The with @ref INPUTSTREAM_COLORSPACE setable color space
+ void SetColorSpace(INPUTSTREAM_COLORSPACE colorSpace) { m_cStructure->m_colorSpace = colorSpace; }
+
+ /// @brief To get with @ref SetColorSpace changed values.
+ INPUTSTREAM_COLORSPACE GetColorSpace() const { return m_cStructure->m_colorSpace; }
+
+ /// @brief Color range if available.
+ ///
+ /// @param[in] colorRange The with @ref INPUTSTREAM_COLORRANGE setable color space
+ void SetColorRange(INPUTSTREAM_COLORRANGE colorRange) { m_cStructure->m_colorRange = colorRange; }
+
+ /// @brief To get with @ref SetColorRange changed values.
+ INPUTSTREAM_COLORRANGE GetColorRange() const { return m_cStructure->m_colorRange; }
+
+ /// @brief Chromaticity coordinates of the source primaries. These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1.
+ ///
+ /// @param[in] colorPrimaries The with @ref INPUTSTREAM_COLORPRIMARIES setable values
+ void SetColorPrimaries(INPUTSTREAM_COLORPRIMARIES colorPrimaries)
+ {
+ m_cStructure->m_colorPrimaries = colorPrimaries;
+ }
+
+ /// @brief To get with @ref SetColorPrimaries changed values.
+ INPUTSTREAM_COLORPRIMARIES GetColorPrimaries() const { return m_cStructure->m_colorPrimaries; }
+
+ /// @brief Color Transfer Characteristic. These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2.
+ ///
+ /// @param[in] colorTransferCharacteristic The with @ref INPUTSTREAM_COLORTRC setable characteristic
+ void SetColorTransferCharacteristic(INPUTSTREAM_COLORTRC colorTransferCharacteristic)
+ {
+ m_cStructure->m_colorTransferCharacteristic = colorTransferCharacteristic;
+ }
+
+ /// @brief To get with @ref SetColorTransferCharacteristic changed values.
+ INPUTSTREAM_COLORTRC GetColorTransferCharacteristic() const
+ {
+ return m_cStructure->m_colorTransferCharacteristic;
+ }
+
+ /// @brief Mastering static Metadata.
+ ///
+ /// Describes the metadata for HDR10, used when video is compressed using High
+ /// Efficiency Video Coding (HEVC). This is used to describe the capabilities
+ /// of the display used to master the content and the luminance values of the
+ /// content.
+ ///
+ /// @param[in] masteringMetadata The with @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamMasteringMetadata setable metadata
+ void SetMasteringMetadata(const kodi::addon::InputstreamMasteringMetadata& masteringMetadata)
+ {
+ m_masteringMetadata = masteringMetadata;
+ m_cStructure->m_masteringMetadata = m_masteringMetadata;
+ }
+
+ /// @brief To get with @ref SetMasteringMetadata changed values.
+ const kodi::addon::InputstreamMasteringMetadata& GetMasteringMetadata() const
+ {
+ return m_masteringMetadata;
+ }
+
+ /// @brief Clear mastering static Metadata.
+ void ClearMasteringMetadata() { m_cStructure->m_masteringMetadata = nullptr; }
+
+ /// @brief Content light static Metadata.
+ ///
+ /// The maximum content light level (MaxCLL) and frame average light level
+ /// (MaxFALL) for the metadata for HDR10.
+ ///
+ /// @param[in] contentLightMetadata The with @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamContentlightMetadata setable metadata
+ void SetContentLightMetadata(
+ const kodi::addon::InputstreamContentlightMetadata& contentLightMetadata)
+ {
+ m_contentLightMetadata = contentLightMetadata;
+ m_cStructure->m_contentLightMetadata = m_contentLightMetadata;
+ }
+
+ /// @brief To get with @ref SetContentLightMetadata changed values.
+ const kodi::addon::InputstreamContentlightMetadata& GetContentLightMetadata() const
+ {
+ return m_contentLightMetadata;
+ }
+
+ /// @brief Clear content light static Metadata.
+ void ClearContentLightMetadata() { m_cStructure->m_contentLightMetadata = nullptr; }
+
+ ///@}
+
+private:
+ InputstreamInfo(const INPUTSTREAM_INFO* stream) : CStructHdl(stream)
+ {
+ SetCryptoSession(StreamCryptoSession(&stream->m_cryptoSession));
+ CopyExtraData();
+ }
+ InputstreamInfo(INPUTSTREAM_INFO* stream) : CStructHdl(stream)
+ {
+ SetCryptoSession(StreamCryptoSession(&stream->m_cryptoSession));
+ CopyExtraData();
+ }
+
+ void CopyExtraData()
+ {
+ if (m_cStructure->m_ExtraData && m_cStructure->m_ExtraSize > 0)
+ {
+ for (unsigned int i = 0; i < m_cStructure->m_ExtraSize; ++i)
+ m_extraData.emplace_back(m_cStructure->m_ExtraData[i]);
+ }
+ if (m_cStructure->m_masteringMetadata)
+ m_masteringMetadata = m_cStructure->m_masteringMetadata;
+ if (m_cStructure->m_contentLightMetadata)
+ m_contentLightMetadata = m_cStructure->m_contentLightMetadata;
+ }
+ std::vector<uint8_t> m_extraData;
+ StreamCryptoSession m_cryptoSession;
+ InputstreamMasteringMetadata m_masteringMetadata;
+ InputstreamContentlightMetadata m_contentLightMetadata;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamTimes class InputstreamTimes
+/// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+/// @brief **Inputstream add-on times**\n
+/// Used on @ref kodi::addon::CInstanceInputStream::GetTimes().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_inputstream_Defs_Interface_InputstreamTimes_Help
+///
+///@{
+class ATTR_DLL_LOCAL InputstreamTimes : public CStructHdl<InputstreamTimes, INPUTSTREAM_TIMES>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceInputStream;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ InputstreamTimes() = default;
+ InputstreamTimes(const InputstreamTimes& stream) : CStructHdl(stream) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamTimes_Help Value Help
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamTimes
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamTimes :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|--------------------
+ /// | **Start time** | `time_t` | @ref InputstreamTimes::SetStartTime "SetStartTime" | @ref InputstreamTimes::GetStartTime "GetStartTime"
+ /// | **PTS start** | `double` | @ref InputstreamTimes::SetPtsStart "SetPtsStart" | @ref InputstreamTimes::GetPtsStart "GetPtsStart"
+ /// | **PTS begin** | `double` | @ref InputstreamTimes::SetPtsBegin "SetPtsBegin" | @ref InputstreamTimes::GetPtsBegin "GetPtsBegin"
+ /// | **PTS end** | `double` | @ref InputstreamTimes::SetPtsEnd "SetPtsEnd" | @ref InputstreamTimes::GetPtsEnd "GetPtsEnd"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamTimes
+ ///@{
+
+ /// @brief Start time in milliseconds
+ void SetStartTime(time_t startTime) const { m_cStructure->startTime = startTime; }
+
+ /// @brief To get with @ref SetStartTime changed values
+ time_t GetStartTime() const { return m_cStructure->startTime; }
+
+ /// @brief Start PTS
+ void SetPtsStart(double ptsStart) const { m_cStructure->ptsStart = ptsStart; }
+
+ /// @brief To get with @ref SetPtsStart changed values
+ double GetPtsStart() const { return m_cStructure->ptsStart; }
+
+ /// @brief Begin PTS
+ void SetPtsBegin(double ptsBegin) const { m_cStructure->ptsBegin = ptsBegin; }
+
+ /// @brief To get with @ref SetPtsBegin changed values
+ double GetPtsBegin() const { return m_cStructure->ptsBegin; }
+
+ /// @brief End PTS
+ void SetPtsEnd(double ptsEnd) const { m_cStructure->ptsEnd = ptsEnd; }
+
+ /// @brief To get with @ref SetPtsEnd changed values
+ double GetPtsEnd() const { return m_cStructure->ptsEnd; }
+
+ ///@}
+
+private:
+ InputstreamTimes(const INPUTSTREAM_TIMES* stream) : CStructHdl(stream) {}
+ InputstreamTimes(INPUTSTREAM_TIMES* stream) : CStructHdl(stream) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//============================================================================
+///
+/// @addtogroup cpp_kodi_addon_inputstream
+/// @brief \cpp_class{ kodi::addon::CInstanceInputStream }
+/// **Inputstream add-on instance**
+///
+/// This instance type is for using input streams to video and audio, to process
+/// and then give them to Kodi.
+///
+/// This usage can be requested under various conditions, for example explicitly
+/// by another addon, by a Mimetype protocol defined in `addon.xml` or supported
+/// file extensions.
+///
+/// In addition, stream files (* .strm) can be linked to an inputstream addon
+/// using <b>`#KODIPROP:inputstream=<ADDON_NAME>`</b>.
+///
+/// Include the header @ref Inputstream.h "#include <kodi/addon-instance/Inputstream.h>"
+/// to use this class.
+///
+/// ----------------------------------------------------------------------------
+///
+/// Here is an example of what the <b>`addon.xml.in`</b> would look like for an inputstream addon:
+///
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="inputstream.myspecialnamefor"
+/// version="1.0.0"
+/// name="My InputStream addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="kodi.inputstream"
+/// extension=".xyz|.zyx"
+/// listitemprops="license_type|license_key|license_data|license_flags"
+/// protocols="myspecialnamefor|myspecialnamefors"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My InputStream addon</summary>
+/// <description lang="en_GB">My InputStream description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+///
+/// At <b>`<extension point="kodi.inputstream" ...>`</b> the basic instance definition is declared, this is intended to identify the addon as an input stream and to see its supported types:
+/// | Name | Description
+/// |------|----------------------
+/// | <b>`point`</b> | The identification of the addon instance to inputstream is mandatory <b>`kodi.inputstream`</b>. In addition, the instance declared in the first <b>`<extension ... />`</b> is also
+/// | <b>`extension`</b> | A filename extension is an identifier specified as a suffix to the name of a computer file where supported by addon.
+/// | <b>`listitemprops`</b> | Values that are available to the addon at @ref InputstreamProperty::GetProperties() and that can be passed to @ref CInstanceInputStream::Open() ith the respective values.
+/// | <b>`protocols`</b> | The streaming protocol is a special protocol supported by the addon for the transmission of streaming media data over a network.
+/// | <b>`library_@PLATFORM@`</b> | The runtime library used for the addon. This is usually declared by cmake and correctly displayed in the translated `addon.xml`.
+///
+///
+/// @remark For more detailed description of the <b>`addon.xml`</b>, see also https://kodi.wiki/view/Addon.xml.
+///
+///
+/// --------------------------------------------------------------------------
+///
+///
+/// **Example:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/Inputstream.h>
+///
+/// class CMyInputstream : public kodi::addon::CInstanceInputStream
+/// {
+/// public:
+/// CMyInputstream(const kodi::addon::IInstanceInfo& instance);
+///
+/// void GetCapabilities(kodi::addon::InputstreamCapabilities& capabilities) override;
+/// bool Open(const kodi::addon::InputstreamProperty& props) override;
+/// void Close() override;
+/// ...
+/// };
+///
+/// CMyInputstream::CMyInputstream(const kodi::addon::IInstanceInfo& instance)
+/// : kodi::addon::CInstanceInputStream(instance)
+/// {
+/// ...
+/// }
+///
+/// void CMyInputstream::GetCapabilities(kodi::addon::InputstreamCapabilities& capabilities)
+/// {
+/// capabilities.SetMask(INPUTSTREAM_SUPPORTS_IDEMUX | INPUTSTREAM_SUPPORTS_PAUSE);
+/// }
+///
+/// void CMyInputstream::Open(const kodi::addon::InputstreamProperty& props)
+/// {
+/// std::string url = props.GetURL();
+/// ...
+/// }
+///
+/// void CMyInputstream::Close()
+/// {
+/// ...
+/// }
+///
+/// ...
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_INPUTSTREAM))
+/// {
+/// kodi::Log(ADDON_LOG_NOTICE, "Creating my Inputstream");
+/// hdl = new CMyInputstream(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyInputstream` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+//------------------------------------------------------------------------------
+class ATTR_DLL_LOCAL CInstanceInputStream : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_inputstream
+ /// @brief Inputstream class constructor used to support multiple instance
+ /// types
+ ///
+ /// @param[in] instance The instance value given to <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>
+ /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to
+ /// allow compatibility to older Kodi versions.
+ ///
+ /// @warning Only use `instance` from the @ref CAddonBase::CreateInstance call.
+ ///
+ explicit CInstanceInputStream(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceInputStream: Creation of multiple together "
+ "with single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_inputstream
+ /// @brief Destructor
+ ///
+ ~CInstanceInputStream() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_inputstream
+ /// @brief Get the list of features that this add-on provides.
+ ///
+ /// Called by Kodi to query the add-on's capabilities.
+ /// Used to check which options should be presented in the UI, which methods to call, etc.
+ /// All capabilities that the add-on supports should be set to true.
+ ///
+ /// @param[out] capabilities The with @ref cpp_kodi_addon_inputstream_Defs_Capabilities defined add-on's capabilities.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities_Help
+ ///
+ /// --------------------------------------------------------------------------
+ /// @note Valid implementation required.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ ///
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// void CMyInputstream::GetCapabilities(kodi::addon::InputstreamCapabilities& capabilities)
+ /// {
+ /// capabilities.SetMask(INPUTSTREAM_SUPPORTS_IDEMUX | INPUTSTREAM_SUPPORTS_PAUSE);
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual void GetCapabilities(kodi::addon::InputstreamCapabilities& capabilities) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_inputstream
+ /// @brief Open a stream.
+ ///
+ /// @param[in] props The used properties about the stream
+ /// @return True if the stream has been opened successfully, false otherwise.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_inputstream_Defs_InputstreamProperty_Help
+ ///
+ /// --------------------------------------------------------------------------
+ /// @note Valid implementation required.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ ///
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// void CMyInputstream::Open(const kodi::addon::InputstreamProperty& props)
+ /// {
+ /// std::string url = props.GetURL();
+ /// std::string license_key = props.GetProperties()["inputstream.myspecialnamefor.license_key"];
+ /// ...
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual bool Open(const kodi::addon::InputstreamProperty& props) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_inputstream
+ /// @brief Close an open stream.
+ ///
+ /// @remarks
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// @note Valid implementation required.
+ ///
+ virtual void Close() = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_inputstream
+ /// @brief Check for real-time streaming
+ ///
+ /// @return true if current stream is real-time
+ ///
+ virtual bool IsRealTimeStream() { return true; }
+ //----------------------------------------------------------------------------
+
+ //############################################################################
+ /// @defgroup cpp_kodi_addon_inputstream_Read 1. Stream read
+ /// @brief **Functions required to read streams direct and demux inside Kodi.**
+ ///
+ /// This part contains at least the functions necessary for addon that have to
+ /// be supported. This can only be ignored if you use your own demux.
+ ///
+ /// The data loaded by Kodi is then processed in it itself. The source does not
+ /// matter, only Kodi must be able to process this stream data itself and is
+ /// therefore limited in some things.
+ ///
+ /// For more complex things, the addon must integrate its own demuxer and,
+ /// if necessary, even its own codec processing (see @ref cpp_kodi_addon_codec "Codec").
+ ///
+ /// @note These are used and must be set by the addon if the @ref INPUTSTREAM_SUPPORTS_IDEMUX
+ /// is <em><b>undefined</b></em> in the capabilities (see @ref GetCapabilities()).
+ /// Otherwise becomes @ref cpp_kodi_addon_inputstream_Demux "demuxing" used.
+ ///
+ /// @ingroup cpp_kodi_addon_inputstream
+ ///@{
+
+ //============================================================================
+ /// @brief Read from an open stream.
+ ///
+ /// @param[in] buffer The buffer to store the data in.
+ /// @param[in] bufferSize The amount of bytes to read.
+ /// @return The amount of bytes that were actually read from the stream.
+ ///
+ virtual int ReadStream(uint8_t* buffer, unsigned int bufferSize) { return -1; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Seek in a stream.
+ ///
+ /// @param[in] position The position to seek to
+ /// @param[in] whence offset relative to<br>
+ /// You can set the value of whence to one of three things:
+ /// | Value | int | Description |
+ /// |:------------:|:-----:|:----------------------------------------------------|
+ /// | **SEEK_SET** | `0` | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
+ /// | **SEEK_CUR** | `1` | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
+ /// | **SEEK_END** | `2` | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
+ ///
+ /// @return Returns the resulting offset location as measured in bytes from
+ /// the beginning of the file. On error, the value -1 is returned.
+ ///
+ /// @remarks Optional and can leaved away or return -1 if this add-on won't
+ /// provide this function.
+ ///
+ virtual int64_t SeekStream(int64_t position, int whence = SEEK_SET) { return -1; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief The position in the stream that's currently being read.
+ ///
+ /// @return Stream position
+ ///
+ /// @remarks Optional and can leaved away or return -1 if this add-on won't
+ /// provide this function.
+ ///
+ virtual int64_t PositionStream() { return -1; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief The Total length of the stream that's currently being read.
+ ///
+ /// @return Length of the stream
+ ///
+ /// @remarks Optional and can leaved away or return -1 if this add-on won't
+ /// provide this function.
+ ///
+ virtual int64_t LengthStream() { return -1; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Obtain the chunk size to use when reading streams.
+ ///
+ /// @return Block chunk size
+ ///
+ /// @remarks Optional and can leaved away or return 0 if this add-on won't
+ /// provide this function.
+ ///
+ virtual int GetBlockSize() { return 0; }
+ //--------------------------------------------------------------------------
+
+ ///@}
+
+ //############################################################################
+ /// @defgroup cpp_kodi_addon_inputstream_Demux 2. Stream demuxing (optional)
+ /// @brief **Read demux streams.**
+ ///
+ /// @note These are used and must be set by the addon if the @ref INPUTSTREAM_SUPPORTS_IDEMUX is set in the capabilities (see @ref GetCapabilities()).
+ ///
+ /// @ingroup cpp_kodi_addon_inputstream
+ ///@{
+
+ //============================================================================
+ /// @brief Get IDs of available streams
+ ///
+ /// @param[in] ids list of used identifications
+ /// @return true if successfully done, otherwise false
+ ///
+ /// @remarks This id's are used to identify wanted data on @ref GetStream call.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ ///
+ /// ~~~~~~~~~~~~~{.cpp}
+ ///
+ /// bool CMyInputstream::GetStreamIds(std::vector<unsigned int>& ids)
+ /// {
+ /// kodi::Log(ADDON_LOG_DEBUG, "GetStreamIds(...)");
+ ///
+ /// if (m_opened)
+ /// {
+ /// // This check not needed to have, the ABI checks also about, but make
+ /// // sure you not give more as 32 streams.
+ /// if (m_myStreams.size() > MAX_STREAM_COUNT)
+ /// {
+ /// kodi::Log(ADDON_LOG_ERROR, "Too many streams, only %u supported", MAX_STREAM_COUNT);
+ /// return false;
+ /// }
+ ///
+ /// ids.emplace_back(m_myAudioStreamId);
+ ///
+ /// for (const auto& streamPair : m_myOtherStreams)
+ /// {
+ /// ids.emplace_back(streamPair.second->uniqueId);
+ /// }
+ /// }
+ ///
+ /// return !ids.empty();
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual bool GetStreamIds(std::vector<unsigned int>& ids) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Function for giving detailed stream information
+ ///
+ /// The associated information is set here for IDs previously given with
+ /// @ref GetStreamIds.
+ ///
+ /// This data is required to identify the associated codec and, if necessary,
+ /// to refer to your own codec (if available in the addon).
+ ///
+ /// @param[in] streamid unique id of stream
+ /// @param[out] stream Information data of wanted stream
+ /// @return true if successfully done, otherwise false
+ ///
+ /// @remarks Available stream id's previously asked by @ref GetStreamIds
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo_Help
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ ///
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// bool CMyInputstream::GetStream(int streamid, kodi::addon::InputstreamInfo& stream)
+ /// {
+ /// // This is just a small example, this type will be significantly larger
+ /// // for larger and more complex streams.
+ /// if (streamid == m_myAudioStreamId)
+ /// {
+ /// // This only a minimal exampl
+ /// stream.SetStreamType(INPUTSTREAM_TYPE_AUDIO);
+ /// stream.SetFeatures(INPUTSTREAM_FEATURE_NONE); // Only added to example, INPUTSTREAM_FEATURE_NONE is default and no need to call
+ /// stream.SetFlags(INPUTSTREAM_FLAG_NONE); // Only added to example, INPUTSTREAM_FLAG_NONE is default and no need to call
+ /// stream.SetCodecName("mp2"); // Codec name, string must by equal with FFmpeg, see https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c
+ /// stream.SetPhysicalIndex(1); // Identifier required to set
+ /// stream.SetLanguage("en");
+ /// stream.SetChannels(2);
+ /// stream.SetSampleRate(48000);
+ /// stream.SetBitRate(0);
+ /// stream.SetBitsPerSample(16);
+ /// }
+ /// else ...
+ /// ...
+ /// return true;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual bool GetStream(int streamid, kodi::addon::InputstreamInfo& stream) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Enable or disable a stream.
+ ///
+ /// A disabled stream does not send demux packets
+ ///
+ /// @param[in] streamid unique id of stream
+ /// @param[in] enable true for enable, false for disable
+ ///
+ /// @remarks Available stream id's previously asked by @ref GetStreamIds
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// @note Valid implementation required.
+ ///
+ virtual void EnableStream(int streamid, bool enable) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Opens a stream for playback.
+ ///
+ /// @param[in] streamid unique id of stream
+ ///
+ /// @remarks Available stream id's previously asked by @ref GetStreamIds
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// @note Valid implementation required.
+ ///
+ virtual bool OpenStream(int streamid) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Reset the demultiplexer in the add-on.
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ ///
+ virtual void DemuxReset() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Abort the demultiplexer thread in the add-on.
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ ///
+ virtual void DemuxAbort() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Flush all data that's currently in the demultiplexer buffer in the add-on.
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ ///
+ virtual void DemuxFlush() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Read the next packet from the demultiplexer, if there is one.
+ ///
+ /// @return The next packet.
+ /// If there is no next packet, then the add-on should return the
+ /// packet created by calling @ref AllocateDemuxPacket "AllocateDemuxPacket(0)" on the callback.
+ /// If the stream changed and Kodi's player needs to be reinitialised,
+ /// then, the add-on should call @ref AllocateDemuxPacket "AllocateDemuxPacket(0)" on the
+ /// callback, and set the streamid to DMX_SPECIALID_STREAMCHANGE and
+ /// return the value.
+ /// The add-on should return <b>`nullptr`</b> if an error occurred.
+ ///
+ /// @remarks Return <b>`nullptr`</b> if this add-on won't provide this function.
+ ///
+ virtual DEMUX_PACKET* DemuxRead() { return nullptr; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify the InputStream addon/demuxer that Kodi wishes to seek the stream by time
+ ///
+ /// Demuxer is required to set stream to an IDR frame
+ ///
+ /// @param[in] time The absolute time since stream start
+ /// @param[in] backwards True to seek to keyframe BEFORE time, else AFTER
+ /// @param[in] startpts can be updated to point to where display should start
+ /// @return True if the seek operation was possible
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ ///
+ virtual bool DemuxSeekTime(double time, bool backwards, double& startpts) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify the InputStream addon/demuxer that Kodi wishes to change playback speed
+ ///
+ /// @param[in] speed The requested playback speed
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ ///
+ virtual void DemuxSetSpeed(int speed) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify current screen resolution
+ ///
+ /// @param[in] width Width to set
+ /// @param[in] height Height to set
+ ///
+ virtual void SetVideoResolution(unsigned int width, unsigned int height) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify current screen resolution and max screen resolution allowed
+ ///
+ /// @param[in] width Width to set
+ /// @param[in] height Height to set
+ /// @param[in] maxWidth Max width allowed
+ /// @param[in] maxHeight Max height allowed
+ ///
+ virtual void SetVideoResolution(unsigned int width,
+ unsigned int height,
+ unsigned int maxWidth,
+ unsigned int maxHeight)
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //=============================================================================
+ /// @brief Allocate a demux packet. Free with @ref FreeDemuxPacket
+ ///
+ /// @param[in] dataSize The size of the data that will go into the packet
+ /// @return The allocated packet
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ DEMUX_PACKET* AllocateDemuxPacket(int dataSize)
+ {
+ return m_instanceData->toKodi->allocate_demux_packet(m_instanceData->toKodi->kodiInstance,
+ dataSize);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Allocate a encrypted demux packet. Free with @ref FreeDemuxPacket
+ ///
+ /// @param[in] dataSize The size of the data that will go into the packet
+ /// @param[in] encryptedSubsampleCount The encrypted subsample count
+ /// @return The allocated packet
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ DEMUX_PACKET* AllocateEncryptedDemuxPacket(int dataSize, unsigned int encryptedSubsampleCount)
+ {
+ return m_instanceData->toKodi->allocate_encrypted_demux_packet(
+ m_instanceData->toKodi->kodiInstance, dataSize, encryptedSubsampleCount);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Free a packet that was allocated with AllocateDemuxPacket
+ ///
+ /// @param[in] packet The packet to free
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ void FreeDemuxPacket(DEMUX_PACKET* packet)
+ {
+ return m_instanceData->toKodi->free_demux_packet(m_instanceData->toKodi->kodiInstance, packet);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //############################################################################
+ /// @defgroup cpp_kodi_addon_inputstream_Time 3. Time (optional)
+ /// @brief **To get stream position time.**
+ ///
+ /// @note These are used and must be set by the addon if the @ref INPUTSTREAM_SUPPORTS_IDISPLAYTIME is set in the capabilities (see @ref GetCapabilities()).
+ ///
+ /// @ingroup cpp_kodi_addon_inputstream
+ ///@{
+
+ //==========================================================================
+ /// @brief Totel time in ms
+ ///
+ /// @return Total time in milliseconds
+ ///
+ /// @remarks
+ ///
+ virtual int GetTotalTime() { return -1; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Playing time in ms
+ ///
+ /// @return Playing time in milliseconds
+ ///
+ /// @remarks
+ ///
+ virtual int GetTime() { return -1; }
+ //--------------------------------------------------------------------------
+
+ ///@}
+
+ //############################################################################
+ /// @defgroup cpp_kodi_addon_inputstream_Times 4. Times (optional)
+ /// @brief **Another way to get stream position time.**
+ ///
+ /// @note These are used and must be set by the addon if the @ref INPUTSTREAM_SUPPORTS_ITIME is set in the capabilities (see @ref GetCapabilities()).
+ ///
+ /// @ingroup cpp_kodi_addon_inputstream
+ ///@{
+
+ //============================================================================
+ /// @brief Get current timing values in PTS scale
+ ///
+ /// @param[out] times The with @ref InputstreamTimes to given times
+ /// @return true if successfully done, false if not
+ ///
+ /// @copydetails cpp_kodi_addon_inputstream_Defs_Times_Help
+ ///
+ /// @remarks
+ ///
+ virtual bool GetTimes(InputstreamTimes& times) { return false; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //############################################################################
+ /// @defgroup cpp_kodi_addon_inputstream_PosTime 5. Position time (optional)
+ /// @brief **Third way get stream position time.**
+ ///
+ /// @note These are used and must be set by the addon if the @ref INPUTSTREAM_SUPPORTS_IPOSTIME is set in the capabilities (see @ref GetCapabilities()).
+ ///
+ /// @ingroup cpp_kodi_addon_inputstream
+ ///@{
+
+ //============================================================================
+ /// @brief Positions inputstream to playing time given in ms
+ ///
+ /// @param[in] ms Position time in milliseconds
+ ///
+ /// @remarks
+ ///
+ virtual bool PosTime(int ms) { return false; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //############################################################################
+ /// @defgroup cpp_kodi_addon_inputstream_Chapter 6. Chapter (optional)
+ /// @brief **Used to get available chapters.**
+ ///
+ /// @note These are used and must be set by the addon if the @ref INPUTSTREAM_SUPPORTS_ICHAPTER is set in the capabilities (see @ref GetCapabilities()).
+ ///
+ /// @ingroup cpp_kodi_addon_inputstream
+ ///@{
+
+ //==========================================================================
+ ///
+ /// @brief Return currently selected chapter
+ ///
+ /// @return Chapter number
+ ///
+ /// @remarks
+ ///
+ virtual int GetChapter() { return -1; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ ///
+ /// @brief Return number of available chapters
+ ///
+ /// @return Chapter count
+ ///
+ /// @remarks
+ ///
+ virtual int GetChapterCount() { return 0; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ ///
+ /// @brief Return name of chapter
+ ///
+ /// @param[in] ch Chapter identifier
+ /// @return Chapter name
+ ///
+ /// @remarks
+ ///
+ virtual const char* GetChapterName(int ch) { return nullptr; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ ///
+ /// @brief Return position if chapter # ch in milliseconds
+ ///
+ /// @param[in] ch Chapter to get position from
+ /// @return Position in milliseconds
+ ///
+ /// @remarks
+ ///
+ virtual int64_t GetChapterPos(int ch) { return 0; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ ///
+ /// @brief Seek to the beginning of chapter # ch
+ ///
+ /// @param[in] ch Chapter to seek
+ /// @return True if successfully done, false if not
+ ///
+ /// @remarks
+ ///
+ virtual bool SeekChapter(int ch) { return false; }
+ //--------------------------------------------------------------------------
+
+ ///@}
+
+private:
+ static int compareVersion(const int v1[3], const int v2[3])
+ {
+ for (unsigned i(0); i < 3; ++i)
+ if (v1[i] != v2[i])
+ return v1[i] - v2[i];
+ return 0;
+ }
+
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ int api[3] = { 0, 0, 0 };
+ sscanf(GetInstanceAPIVersion().c_str(), "%d.%d.%d", &api[0], &api[1], &api[2]);
+
+ instance->hdl = this;
+ instance->inputstream->toAddon->open = ADDON_Open;
+ instance->inputstream->toAddon->close = ADDON_Close;
+ instance->inputstream->toAddon->get_capabilities = ADDON_GetCapabilities;
+
+ instance->inputstream->toAddon->get_stream_ids = ADDON_GetStreamIds;
+ instance->inputstream->toAddon->get_stream = ADDON_GetStream;
+ instance->inputstream->toAddon->enable_stream = ADDON_EnableStream;
+ instance->inputstream->toAddon->open_stream = ADDON_OpenStream;
+ instance->inputstream->toAddon->demux_reset = ADDON_DemuxReset;
+ instance->inputstream->toAddon->demux_abort = ADDON_DemuxAbort;
+ instance->inputstream->toAddon->demux_flush = ADDON_DemuxFlush;
+ instance->inputstream->toAddon->demux_read = ADDON_DemuxRead;
+ instance->inputstream->toAddon->demux_seek_time = ADDON_DemuxSeekTime;
+ instance->inputstream->toAddon->demux_set_speed = ADDON_DemuxSetSpeed;
+ instance->inputstream->toAddon->set_video_resolution = ADDON_SetVideoResolution;
+
+ instance->inputstream->toAddon->get_total_time = ADDON_GetTotalTime;
+ instance->inputstream->toAddon->get_time = ADDON_GetTime;
+
+ instance->inputstream->toAddon->get_times = ADDON_GetTimes;
+ instance->inputstream->toAddon->pos_time = ADDON_PosTime;
+
+ instance->inputstream->toAddon->read_stream = ADDON_ReadStream;
+ instance->inputstream->toAddon->seek_stream = ADDON_SeekStream;
+ instance->inputstream->toAddon->position_stream = ADDON_PositionStream;
+ instance->inputstream->toAddon->length_stream = ADDON_LengthStream;
+ instance->inputstream->toAddon->is_real_time_stream = ADDON_IsRealTimeStream;
+
+ // Added on 2.0.10
+ instance->inputstream->toAddon->get_chapter = ADDON_GetChapter;
+ instance->inputstream->toAddon->get_chapter_count = ADDON_GetChapterCount;
+ instance->inputstream->toAddon->get_chapter_name = ADDON_GetChapterName;
+ instance->inputstream->toAddon->get_chapter_pos = ADDON_GetChapterPos;
+ instance->inputstream->toAddon->seek_chapter = ADDON_SeekChapter;
+
+ // Added on 2.0.12
+ instance->inputstream->toAddon->block_size_stream = ADDON_GetBlockSize;
+
+ /*
+ // Way to include part on new API version
+ int minPartVersion[3] = { 3, 0, 0 };
+ if (compareVersion(api, minPartVersion) >= 0)
+ {
+
+ }
+ */
+
+ m_instanceData = instance->inputstream;
+ m_instanceData->toAddon->addonInstance = this;
+ }
+
+ inline static bool ADDON_Open(const AddonInstance_InputStream* instance,
+ INPUTSTREAM_PROPERTY* props)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->Open(props);
+ }
+
+ inline static void ADDON_Close(const AddonInstance_InputStream* instance)
+ {
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->Close();
+ }
+
+ inline static void ADDON_GetCapabilities(const AddonInstance_InputStream* instance,
+ INPUTSTREAM_CAPABILITIES* capabilities)
+ {
+ InputstreamCapabilities caps(capabilities);
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetCapabilities(caps);
+ }
+
+
+ // IDemux
+ inline static bool ADDON_GetStreamIds(const AddonInstance_InputStream* instance,
+ struct INPUTSTREAM_IDS* ids)
+ {
+ std::vector<unsigned int> idList;
+ bool ret =
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetStreamIds(idList);
+ if (ret)
+ {
+ for (size_t i = 0; i < idList.size() && i < INPUTSTREAM_MAX_STREAM_COUNT; ++i)
+ {
+ ids->m_streamCount++;
+ ids->m_streamIds[i] = idList[i];
+ }
+ }
+ return ret;
+ }
+
+ inline static bool ADDON_GetStream(
+ const AddonInstance_InputStream* instance,
+ int streamid,
+ struct INPUTSTREAM_INFO* info,
+ KODI_HANDLE* demuxStream,
+ KODI_HANDLE (*transfer_stream)(KODI_HANDLE handle,
+ int streamId,
+ struct INPUTSTREAM_INFO* stream))
+ {
+ InputstreamInfo infoData(info);
+ bool ret = static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->GetStream(streamid, infoData);
+ if (ret && transfer_stream)
+ {
+ // Do this with given callback to prevent memory problems and leaks. This
+ // then create on Kodi the needed class where then given back on demuxStream.
+ *demuxStream = transfer_stream(instance->toKodi->kodiInstance, streamid, info);
+ }
+ return ret;
+ }
+
+ inline static void ADDON_EnableStream(const AddonInstance_InputStream* instance,
+ int streamid,
+ bool enable)
+ {
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->EnableStream(streamid, enable);
+ }
+
+ inline static bool ADDON_OpenStream(const AddonInstance_InputStream* instance, int streamid)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->OpenStream(streamid);
+ }
+
+ inline static void ADDON_DemuxReset(const AddonInstance_InputStream* instance)
+ {
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->DemuxReset();
+ }
+
+ inline static void ADDON_DemuxAbort(const AddonInstance_InputStream* instance)
+ {
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->DemuxAbort();
+ }
+
+ inline static void ADDON_DemuxFlush(const AddonInstance_InputStream* instance)
+ {
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->DemuxFlush();
+ }
+
+ inline static DEMUX_PACKET* ADDON_DemuxRead(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->DemuxRead();
+ }
+
+ inline static bool ADDON_DemuxSeekTime(const AddonInstance_InputStream* instance,
+ double time,
+ bool backwards,
+ double* startpts)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->DemuxSeekTime(time, backwards, *startpts);
+ }
+
+ inline static void ADDON_DemuxSetSpeed(const AddonInstance_InputStream* instance, int speed)
+ {
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->DemuxSetSpeed(speed);
+ }
+
+ inline static void ADDON_SetVideoResolution(const AddonInstance_InputStream* instance,
+ unsigned int width,
+ unsigned int height,
+ unsigned int maxWidth,
+ unsigned int maxHeight)
+ {
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->SetVideoResolution(width, height);
+ static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->SetVideoResolution(width, height, maxWidth, maxHeight);
+ }
+
+ // IDisplayTime
+ inline static int ADDON_GetTotalTime(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetTotalTime();
+ }
+
+ inline static int ADDON_GetTime(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetTime();
+ }
+
+ // ITime
+ inline static bool ADDON_GetTimes(const AddonInstance_InputStream* instance,
+ INPUTSTREAM_TIMES* times)
+ {
+ InputstreamTimes cppTimes(times);
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetTimes(cppTimes);
+ }
+
+ // IPosTime
+ inline static bool ADDON_PosTime(const AddonInstance_InputStream* instance, int ms)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->PosTime(ms);
+ }
+
+ inline static int ADDON_GetChapter(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetChapter();
+ }
+
+ inline static int ADDON_GetChapterCount(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetChapterCount();
+ }
+
+ inline static const char* ADDON_GetChapterName(const AddonInstance_InputStream* instance, int ch)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetChapterName(ch);
+ }
+
+ inline static int64_t ADDON_GetChapterPos(const AddonInstance_InputStream* instance, int ch)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetChapterPos(ch);
+ }
+
+ inline static bool ADDON_SeekChapter(const AddonInstance_InputStream* instance, int ch)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->SeekChapter(ch);
+ }
+
+ inline static int ADDON_ReadStream(const AddonInstance_InputStream* instance,
+ uint8_t* buffer,
+ unsigned int bufferSize)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->ReadStream(buffer, bufferSize);
+ }
+
+ inline static int64_t ADDON_SeekStream(const AddonInstance_InputStream* instance,
+ int64_t position,
+ int whence)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)
+ ->SeekStream(position, whence);
+ }
+
+ inline static int64_t ADDON_PositionStream(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->PositionStream();
+ }
+
+ inline static int64_t ADDON_LengthStream(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->LengthStream();
+ }
+
+ inline static int ADDON_GetBlockSize(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->GetBlockSize();
+ }
+
+ inline static bool ADDON_IsRealTimeStream(const AddonInstance_InputStream* instance)
+ {
+ return static_cast<CInstanceInputStream*>(instance->toAddon->addonInstance)->IsRealTimeStream();
+ }
+
+ AddonInstance_InputStream* m_instanceData;
+};
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h
new file mode 100644
index 0000000..0ee71e2
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h
@@ -0,0 +1,3568 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../c-api/addon-instance/pvr.h"
+#include "pvr/ChannelGroups.h"
+#include "pvr/Channels.h"
+#include "pvr/EDL.h"
+#include "pvr/EPG.h"
+#include "pvr/General.h"
+#include "pvr/MenuHook.h"
+#include "pvr/Providers.h"
+#include "pvr/Recordings.h"
+#include "pvr/Stream.h"
+#include "pvr/Timers.h"
+
+#ifdef __cplusplus
+
+/*!
+ * @internal
+ * @brief PVR "C++" API interface
+ *
+ * In this field are the pure addon-side C++ data.
+ *
+ * @note Changes can be made without problems and have no influence on other
+ * PVR addons that have already been created.\n
+ * \n
+ * Therefore, @ref ADDON_INSTANCE_VERSION_PVR_MIN can be ignored for these
+ * fields and only the @ref ADDON_INSTANCE_VERSION_PVR needs to be increased.\n
+ * \n
+ * Only must be min version increased if a new compile of addon breaks after
+ * changes here.
+ *
+ * Have by add of new parts a look about **Doxygen** `\@ingroup`, so that
+ * added parts included in documentation.
+ *
+ * If you add addon side related documentation, where his dev need know, use `///`.
+ * For parts only for Kodi make it like here.
+ *
+ * @endinternal
+ */
+
+namespace kodi
+{
+namespace addon
+{
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Doxygen group set for the definitions
+//{{{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_pvr
+/// @brief **PVR client add-on instance definition values**\n
+/// All PVR functions associated data structures.
+///
+/// Used to exchange the available options between Kodi and addon.\n
+/// The groups described here correspond to the groups of functions on PVR
+/// instance class.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_General 1. General
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **PVR add-on general variables**\n
+/// Used to exchange the available options between Kodi and addon.
+///
+/// This group also includes @ref cpp_kodi_addon_pvr_Defs_PVRCapabilities with
+/// which Kodi an @ref kodi::addon::CInstancePVRClient::GetCapabilities()
+/// queries the supported **modules** of the addon.
+///
+/// The standard values are also below, once for error messages and once to
+/// @ref kodi::addon::CInstancePVRClient::ConnectionStateChange() to give Kodi
+/// any information.
+///
+///@{
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_General_Inputstream class PVRStreamProperty & definition PVR_STREAM_PROPERTY
+/// @ingroup cpp_kodi_addon_pvr_Defs_General
+/// @brief **Inputstream variables**\n
+/// This includes values related to the outside of PVR available inputstream
+/// system.
+///
+/// This can be by separate instance on same addon, by handling in Kodi itself
+/// or to reference of another addon where support needed inputstream.
+///
+/// @note This is complete independent from own system included here
+/// @ref cpp_kodi_addon_pvr_Streams "inputstream".
+///
+//------------------------------------------------------------------------------
+///@}
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_Channel 2. Channel
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **PVR add-on channel**\n
+/// Used to exchange the available channel options between Kodi and addon.
+///
+/// Modules here are mainly intended for @ref cpp_kodi_addon_pvr_Channels "channels",
+/// but are also used on other modules to identify the respective TV/radio
+/// channel.
+///
+/// Because of @ref cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus and
+/// @ref cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo is a special case at
+/// this point. This is currently only used on running streams, but it may be
+/// possible that this must always be usable in connection with PiP in the
+/// future.
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_ChannelGroup 3. Channel Group
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **PVR add-on channel group**\n
+/// This group contains data classes and values which are used in PVR on
+/// @ref cpp_kodi_addon_pvr_supportsChannelGroups "channel groups".
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_epg 4. EPG Tag
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **PVR add-on EPG data**\n
+/// Used on @ref cpp_kodi_addon_pvr_EPGTag "EPG methods in PVR instance class".
+///
+/// See related modules about, also below in this view are few macros where
+/// default values of associated places.
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_Recording 5. Recording
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **Representation of a recording**\n
+/// Used to exchange the available recording data between Kodi and addon on
+/// @ref cpp_kodi_addon_pvr_Recordings "Recordings methods in PVR instance class".
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_Timer 6. Timer
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **PVR add-on timer data**\n
+/// Used to exchange the available timer data between Kodi and addon on
+/// @ref cpp_kodi_addon_pvr_Timers "Timers methods in PVR instance class".
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_Provider 7. Provider
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **Representation of a provider**\n
+/// For list of all providers from the backend.
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_Menuhook 8. Menuhook
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **PVR Context menu data**\n
+/// Define data for the context menus available to the user
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_EDLEntry 9. Edit decision list (EDL)
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **An edit decision list or EDL is used in the post-production process
+/// of film editing and video editing**\n
+/// Used on @ref kodi::addon::CInstancePVRClient::GetEPGTagEdl and
+/// @ref kodi::addon::CInstancePVRClient::GetRecordingEdl
+///
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_pvr_Defs_Stream 10. Inputstream
+/// @ingroup cpp_kodi_addon_pvr_Defs
+/// @brief **Inputstream**\n
+/// This includes classes and values that are used in the PVR inputstream.
+///
+/// Used on @ref cpp_kodi_addon_pvr_Streams "Inputstream methods in PVR instance class".
+///
+/// @note The parts here will be removed in the future and replaced by the
+/// separate @ref cpp_kodi_addon_inputstream "inputstream addon instance".
+/// If there is already a possibility, new addons should do it via the
+/// inputstream instance.
+///
+//------------------------------------------------------------------------------
+
+//}}}
+//______________________________________________________________________________
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" PVR addon instance class
+//{{{
+
+//==============================================================================
+/// @addtogroup cpp_kodi_addon_pvr
+/// @brief \cpp_class{ kodi::addon::CInstancePVRClient }
+/// **PVR client add-on instance**
+///
+/// Kodi features powerful [Live TV](https://kodi.wiki/view/Live_TV) and
+/// [video recording (DVR/PVR)](http://en.wikipedia.org/wiki/Digital_video_recorder)
+/// abilities using a very flexible distributed application structure. That is, by
+/// leveraging other existing third-party
+/// [PVR backend applications](https://kodi.wiki/view/PVR_backend) or
+/// [DVR devices](https://kodi.wiki/view/PVR_backend)
+/// that specialize in receiving television signals and also support the same type
+/// of [client–server model](http://en.wikipedia.org/wiki/client%E2%80%93server_model)
+/// which Kodi uses, (following a [frontend-backend](http://en.wikipedia.org/wiki/Front_and_back_ends)
+/// design principle for [separation of concerns](http://en.wikipedia.org/wiki/Separation_of_concerns)),
+/// these PVR features in Kodi allow you to watch Live TV, listen to radio, view an EPG TV-Guide
+/// and schedule recordings, and also enables many other TV related features, all using
+/// Kodi as your primary interface once the initial pairing connection and
+/// configuration have been done.
+///
+/// @note It is very important to understand that with "Live TV" in the reference
+/// to PVR in Kodi, we do not mean [streaming video](http://en.wikipedia.org/wiki/Streaming_media)
+/// from the internet via websites providing [free content](https://kodi.wiki/view/Free_content)
+/// or online services such as Netflix, Hulu, Vudu and similar, no matter if that
+/// content is actually streamed live or not. If that is what you are looking for
+/// then you might want to look into [Video Addons](https://kodi.wiki/view/Add-ons)
+/// for Kodi instead, (which again is not the same as the "PVR" or "Live TV" we
+/// discuss in this article), but remember that [Kodi does not provide any video
+/// content or video streaming services](https://kodi.wiki/view/Free_content).
+///
+/// The use of the PVR is based on the @ref CInstancePVRClient.
+///
+/// Include the header @ref PVR.h "#include <kodi/addon-instance/PVR.h>"
+/// to use this class.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// Here is an example of what the <b>`addon.xml.in`</b> would look like for an PVR addon:
+///
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="pvr.myspecialnamefor"
+/// version="1.0.0"
+/// name="My special PVR addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="kodi.pvrclient"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My PVR addon addon</summary>
+/// <description lang="en_GB">My PVR addon description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+///
+/// At <b>`<extension point="kodi.pvrclient" ...>`</b> the basic instance definition is declared, this is intended to identify the addon as an PVR and to see its supported types:
+/// | Name | Description
+/// |------|----------------------
+/// | <b>`point`</b> | The identification of the addon instance to inputstream is mandatory <b>`kodi.pvrclient`</b>. In addition, the instance declared in the first <b>`<extension ... />`</b> is also the main type of addon.
+/// | <b>`library_@PLATFORM@`</b> | The runtime library used for the addon. This is usually declared by cmake and correctly displayed in the translated `addon.xml`.
+///
+///
+/// @remark For more detailed description of the <b>`addon.xml`</b>, see also https://kodi.wiki/view/Addon.xml.
+///
+///
+/// --------------------------------------------------------------------------
+///
+/// **Example:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/PVR.h>
+///
+/// class CMyPVRClient : public ::kodi::addon::CInstancePVRClient
+/// {
+/// public:
+/// CMyPVRClient(const kodi::addon::IInstanceInfo& instance);
+///
+/// PVR_ERROR GetCapabilities(kodi::addon::PVRCapabilities& capabilities) override;
+/// PVR_ERROR GetBackendName(std::string& name) override;
+/// PVR_ERROR GetBackendVersion(std::string& version) override;
+///
+/// PVR_ERROR GetProvidersAmount(int& amount) override;
+/// PVR_ERROR GetProviders(std::vector<kodi::addon::PVRProvider>& providers) override;
+/// PVR_ERROR GetChannelsAmount(int& amount) override;
+/// PVR_ERROR GetChannels(bool radio, std::vector<kodi::addon::PVRChannel>& channels) override;
+/// PVR_ERROR GetChannelStreamProperties(const kodi::addon::PVRChannel& channel,
+/// std::vector<kodi::addon::PVRStreamProperty>& properties) override;
+///
+/// private:
+/// std::vector<kodi::addon::PVRChannel> m_myChannels;
+/// };
+///
+/// CMyPVRClient::CMyPVRClient(const kodi::addon::IInstanceInfo& instance)
+/// : CInstancePVRClient(instance)
+/// {
+/// kodi::addon::PVRChannel channel;
+/// channel.SetUniqueId(123);
+/// channel.SetChannelNumber(1);
+/// channel.SetChannelName("My test channel");
+/// m_myChannels.push_back(channel);
+/// }
+///
+/// PVR_ERROR CMyPVRClient::GetCapabilities(kodi::addon::PVRCapabilities& capabilities)
+/// {
+/// capabilities.SetSupportsTV(true);
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// PVR_ERROR CMyPVRClient::GetBackendName(std::string& name)
+/// {
+/// name = "My special PVR client";
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// PVR_ERROR CMyPVRClient::GetBackendVersion(std::string& version)
+/// {
+/// version = "1.0.0";
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// PVR_ERROR CMyInstance::GetProvidersAmount(int& amount)
+/// {
+/// amount = m_myProviders.size();
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// PVR_ERROR CMyPVRClient::GetProviders(std::vector<kodi::addon::PVRProvider>& providers)
+/// {
+/// providers = m_myProviders;
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// PVR_ERROR CMyInstance::GetChannelsAmount(int& amount)
+/// {
+/// amount = m_myChannels.size();
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// PVR_ERROR CMyPVRClient::GetChannels(bool radio, std::vector<kodi::addon::PVRChannel>& channels)
+/// {
+/// channels = m_myChannels;
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// PVR_ERROR CMyPVRClient::GetChannelStreamProperties(const kodi::addon::PVRChannel& channel,
+/// std::vector<kodi::addon::PVRStreamProperty>& properties)
+/// {
+/// if (channel.GetUniqueId() == 123)
+/// {
+/// properties.push_back(PVR_STREAM_PROPERTY_STREAMURL, "http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4");
+/// properties.push_back(PVR_STREAM_PROPERTY_ISREALTIMESTREAM, "true");
+/// return PVR_ERROR_NO_ERROR;
+/// }
+/// return PVR_ERROR_UNKNOWN;
+/// }
+///
+/// ...
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public ::kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_PVR))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my PVR client instance");
+/// hdl = new CMyPVRClient(instance, version);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyPVRClient` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+class ATTR_DLL_LOCAL CInstancePVRClient : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Base 1. Basic functions
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief **Functions to manage the addon and get basic information about it**\n
+ /// These are e.g. @ref GetCapabilities to know supported groups at
+ /// this addon or the others to get information about the source of the PVR
+ /// stream.
+ ///
+ /// The with "Valid implementation required." declared functions are mandatory,
+ /// all others are an option.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Basic parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Base_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Base_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief PVR client class constructor.
+ ///
+ /// Used by an add-on that only supports only PVR and only in one instance.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/addon-instance/PVR.h>
+ /// ...
+ ///
+ /// class ATTR_DLL_LOCAL CPVRExample
+ /// : public kodi::addon::CAddonBase,
+ /// public kodi::addon::CInstancePVRClient
+ /// {
+ /// public:
+ /// CPVRExample()
+ /// {
+ /// }
+ ///
+ /// ~CPVRExample() override;
+ /// {
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDONCREATOR(CPVRExample)
+ /// ~~~~~~~~~~~~~
+ ///
+ CInstancePVRClient() : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstancePVRClient: Creation of more as one in single "
+ "instance way is not allowed!");
+
+ SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
+ CPrivateBase::m_interface->globalSingleInstance = this;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief PVR client class constructor used to support multiple instance
+ /// types.
+ ///
+ /// @param[in] instance The instance value given to
+ /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// class CMyPVRClient : public ::kodi::addon::CInstancePVRClient
+ /// {
+ /// public:
+ /// CMyPVRClient(const kodi::addon::IInstanceInfo& instance)
+ /// : CInstancePVRClient(instance)
+ /// {
+ /// ...
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ /// KODI_ADDON_INSTANCE_HDL& hdl)
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my PVR client instance");
+ /// hdl = new CMyPVRClient(instance);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ explicit CInstancePVRClient(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstancePVRClient: Creation of multiple together with "
+ "single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Destructor
+ ///
+ ~CInstancePVRClient() override = default;
+ //----------------------------------------------------------------------------
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @brief Get the list of features that this add-on provides.
+ ///
+ /// Called by Kodi to query the add-on's capabilities.
+ /// Used to check which options should be presented in the UI, which methods to call, etc.
+ /// All capabilities that the add-on supports should be set to true.
+ ///
+ /// @param capabilities The with @ref cpp_kodi_addon_pvr_Defs_PVRCapabilities defined add-on's capabilities.
+ /// @return @ref PVR_ERROR_NO_ERROR if the properties were fetched successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRCapabilities_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// PVR_ERROR CMyPVRClient::GetCapabilities(kodi::addon::PVRCapabilities& capabilities)
+ /// {
+ /// capabilities.SetSupportsTV(true);
+ /// capabilities.SetSupportsEPG(true);
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @note Valid implementation required.
+ ///
+ virtual PVR_ERROR GetCapabilities(kodi::addon::PVRCapabilities& capabilities) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the name reported by the backend that will be displayed in the UI.
+ ///
+ /// @param[out] name The name reported by the backend that will be displayed in the UI.
+ /// @return @ref PVR_ERROR_NO_ERROR if successfully done
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// PVR_ERROR CMyPVRClient::GetBackendName(std::string& name)
+ /// {
+ /// name = "My special PVR client";
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @note Valid implementation required.
+ ///
+ virtual PVR_ERROR GetBackendName(std::string& name) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the version string reported by the backend that will be
+ /// displayed in the UI.
+ ///
+ /// @param[out] version The version string reported by the backend that will be
+ /// displayed in the UI.
+ /// @return @ref PVR_ERROR_NO_ERROR if successfully done
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// PVR_ERROR CMyPVRClient::GetBackendVersion(std::string& version)
+ /// {
+ /// version = "1.0.0";
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @note Valid implementation required.
+ ///
+ virtual PVR_ERROR GetBackendVersion(std::string& version) = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the hostname of the pvr backend server
+ ///
+ /// @param[out] hostname Hostname as ip address or alias. If backend does not
+ /// utilize a server, return empty string.
+ /// @return @ref PVR_ERROR_NO_ERROR if successfully done
+ ///
+ virtual PVR_ERROR GetBackendHostname(std::string& hostname) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief To get the connection string reported by the backend that will be
+ /// displayed in the UI.
+ ///
+ /// @param[out] connection The connection string reported by the backend that
+ /// will be displayed in the UI.
+ /// @return @ref PVR_ERROR_NO_ERROR if successfully done
+ ///
+ virtual PVR_ERROR GetConnectionString(std::string& connection)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the disk space reported by the backend (if supported).
+ ///
+ /// @param[in] total The total disk space in KiB.
+ /// @param[in] used The used disk space in KiB.
+ /// @return @ref PVR_ERROR_NO_ERROR if the drive space has been fetched
+ /// successfully.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// PVR_ERROR CMyPVRClient::GetDriveSpace(uint64_t& total, uint64_t& used)
+ /// {
+ /// total = 100 * 1024 * 1024; // To set complete size of drive in KiB (100GB)
+ /// used = 12232424; // To set the used amount
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetDriveSpace(uint64_t& total, uint64_t& used)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Call one of the settings related menu hooks (if supported).
+ ///
+ /// Supported @ref cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook "menu hook "
+ /// instances have to be added in `constructor()`, by calling @ref AddMenuHook()
+ /// on the callback.
+ ///
+ /// @param[in] menuhook The hook to call.
+ /// @return @ref PVR_ERROR_NO_ERROR if the hook was called successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// PVR_ERROR CMyPVRClient::CallSettingsMenuHook(const kodi::addon::PVRMenuhook& menuhook)
+ /// {
+ /// if (menuhook.GetHookId() == 2)
+ /// kodi::QueueNotification(QUEUE_INFO, "", kodi::GetLocalizedString(menuhook.GetLocalizedStringId()));
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR CallSettingsMenuHook(const kodi::addon::PVRMenuhook& menuhook)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\nAdd or replace a menu hook for the context menu for this add-on
+ ///
+ /// This is a callback function, called from addon to give Kodi his context menu's.
+ ///
+ /// @param[in] menuhook The with @ref cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook defined hook to add
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here's an example of the use of it:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/addon-instance/PVR.h>
+ /// ...
+ ///
+ /// {
+ /// kodi::addon::PVRMenuhook hook;
+ /// hook.SetHookId(1);
+ /// hook.SetCategory(PVR_MENUHOOK_CHANNEL);
+ /// hook.SetLocalizedStringId(30000);
+ /// AddMenuHook(hook);
+ /// }
+ ///
+ /// {
+ /// kodi::addon::PVRMenuhook hook;
+ /// hook.SetHookId(2);
+ /// hook.SetCategory(PVR_MENUHOOK_SETTING);
+ /// hook.SetLocalizedStringId(30001);
+ /// AddMenuHook(hook);
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ /// **Here another way:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/addon-instance/PVR.h>
+ /// ...
+ ///
+ /// AddMenuHook(kodi::addon::PVRMenuhook(1, 30000, PVR_MENUHOOK_CHANNEL));
+ /// AddMenuHook(kodi::addon::PVRMenuhook(2, 30001, PVR_MENUHOOK_SETTING));
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ inline void AddMenuHook(const kodi::addon::PVRMenuhook& hook)
+ {
+ m_instanceData->toKodi->AddMenuHook(m_instanceData->toKodi->kodiInstance, hook);
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Notify a state change for a PVR backend connection.
+ ///
+ /// @param[in] connectionString The connection string reported by the backend
+ /// that can be displayed in the UI.
+ /// @param[in] newState The by @ref PVR_CONNECTION_STATE defined new state.
+ /// @param[in] message A localized addon-defined string representing the new
+ /// state, that can be displayed in the UI or **empty** if
+ /// the Kodi-defined default string for the new state
+ /// shall be displayed.
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ ///
+ /// **Here's an example of the use of it:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/addon-instance/PVR.h>
+ /// #include <kodi/General.h> /* for kodi::GetLocalizedString(...) */
+ /// ...
+ ///
+ /// ConnectionStateChange("PVR demo connection lost", PVR_CONNECTION_STATE_DISCONNECTED, kodi::GetLocalizedString(30005, "Lost connection to Server"););
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ inline void ConnectionStateChange(const std::string& connectionString,
+ PVR_CONNECTION_STATE newState,
+ const std::string& message)
+ {
+ m_instanceData->toKodi->ConnectionStateChange(
+ m_instanceData->toKodi->kodiInstance, connectionString.c_str(), newState, message.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Get user data path of the PVR addon.
+ ///
+ /// @return Path of current Kodi user
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ /// @note Alternatively, @ref kodi::GetAddonPath() can be used for this.
+ ///
+ inline std::string UserPath() const { return m_instanceData->props->strUserPath; }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Get main client path of the PVR addon.
+ ///
+ /// @return Path of addon client
+ ///
+ /// @remarks Only called from addon itself.
+ ///
+ /// @note Alternatively, @ref kodi::GetBaseUserPath() can be used for this.
+ ///
+ inline std::string ClientPath() const { return m_instanceData->props->strClientPath; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Channels 2. Channels (required)
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief **Functions to get available TV or Radio channels**\n
+ /// These are mandatory functions for using this addon to get the available
+ /// channels.
+ ///
+ /// @remarks Either @ref PVRCapabilities::SetSupportsTV "SetSupportsTV()" or
+ /// @ref PVRCapabilities::SetSupportsRadio "SetSupportsRadio()" is required to
+ /// be set to <b>`true`</b>.\n
+ /// If a channel changes after the initial import, or if a new one was added,
+ /// then the add-on should call @ref TriggerChannelUpdate().
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Channel parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Channels_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Channels_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief The total amount of providers on the backend
+ ///
+ /// @param[out] amount The total amount of providers on the backend
+ /// @return @ref PVR_ERROR_NO_ERROR if the amount has been fetched successfully.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsProviders
+ /// "supportsProviders" is set to true.
+ ///
+ virtual PVR_ERROR GetProvidersAmount(int& amount) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Request the list of all providers from the backend.
+ ///
+ /// @param[out] results The channels defined with
+ /// @ref cpp_kodi_addon_pvr_Defs_PVRProvider and
+ /// available at the addon, then transferred with
+ /// @ref cpp_kodi_addon_pvr_Defs_PVRProvidersResultSet.
+ /// @return @ref PVR_ERROR_NO_ERROR if the list has been fetched successfully.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsProviders
+ /// "supportsProviders" is set to true.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRProvider_Help
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetProviders(kodi::addon::PVRProvidersResultSet& results)
+ /// {
+ /// // Minimal demo example, in reality bigger and loop to transfer all
+ /// kodi::addon::PVRProvider provider;
+ /// provider.SetUniqueId(123);
+ /// provider.SetProviderName("My provider name");
+ /// provider.SetProviderType(PVR_PROVIDER_TYPE_SATELLITE);
+ /// ...
+ ///
+ /// // Give it now to Kodi
+ /// results.Add(provider);
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetProviders(kodi::addon::PVRProvidersResultSet& results)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Request Kodi to update it's list of providers.
+ ///
+ /// @remarks Only called from addon itself.
+ ///
+ inline void TriggerProvidersUpdate()
+ {
+ m_instanceData->toKodi->TriggerProvidersUpdate(m_instanceData->toKodi->kodiInstance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief The total amount of channels on the backend
+ ///
+ /// @param[out] amount The total amount of channels on the backend
+ /// @return @ref PVR_ERROR_NO_ERROR if the amount has been fetched successfully.
+ ///
+ /// @remarks Valid implementation required.
+ ///
+ virtual PVR_ERROR GetChannelsAmount(int& amount) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Request the list of all channels from the backend.
+ ///
+ /// @param[in] radio True to get the radio channels, false to get the TV channels.
+ /// @param[out] results The channels defined with @ref cpp_kodi_addon_pvr_Defs_Channel_PVRChannel
+ /// and available at the addon, them transferred with
+ /// @ref cpp_kodi_addon_pvr_Defs_Channel_PVRChannelsResultSet.
+ /// @return @ref PVR_ERROR_NO_ERROR if the list has been fetched successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRChannel_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @remarks
+ /// If @ref PVRCapabilities::SetSupportsTV() is set to
+ /// <b>`true`</b>, a valid result set needs to be provided for <b>`radio = false`</b>.\n
+ /// If @ref PVRCapabilities::SetSupportsRadio() is set to
+ /// <b>`true`</b>, a valid result set needs to be provided for <b>`radio = true`</b>.
+ /// At least one of these two must provide a valid result set.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetChannels(bool radio, kodi::addon::PVRChannelsResultSet& results)
+ /// {
+ /// // Minimal demo example, in reality bigger and loop to transfer all
+ /// kodi::addon::PVRChannel channel;
+ /// channel.SetUniqueId(123);
+ /// channel.SetIsRadio(false);
+ /// channel.SetChannelNumber(1);
+ /// channel.SetChannelName("My channel name");
+ /// ...
+ ///
+ /// // Give it now to Kodi
+ /// results.Add(channel);
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetChannels(bool radio, kodi::addon::PVRChannelsResultSet& results)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the stream properties for a channel from the backend.
+ ///
+ /// @param[in] channel The channel to get the stream properties for.
+ /// @param[out] properties the properties required to play the stream.
+ /// @return @ref PVR_ERROR_NO_ERROR if the stream is available.
+ ///
+ /// @remarks If @ref PVRCapabilities::SetSupportsTV "SetSupportsTV" or
+ /// @ref PVRCapabilities::SetSupportsRadio "SetSupportsRadio" are set to true
+ /// and @ref PVRCapabilities::SetHandlesInputStream "SetHandlesInputStream" is
+ /// set to false.\n\n
+ /// In this case the implementation must fill the property @ref PVR_STREAM_PROPERTY_STREAMURL
+ /// with the URL Kodi should resolve to playback the channel.
+ ///
+ /// @note The value directly related to inputstream must always begin with the
+ /// name of the associated add-on, e.g. <b>`"inputstream.adaptive.manifest_update_parameter"`</b>.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetChannelStreamProperties(const kodi::addon::PVRChannel& channel,
+ /// std::vector<kodi::addon::PVRStreamProperty>& properties)
+ /// {
+ /// ...
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "inputstream.adaptive");
+ /// properties.emplace_back("inputstream.adaptive.manifest_type", "mpd");
+ /// properties.emplace_back("inputstream.adaptive.manifest_update_parameter", "full");
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_MIMETYPE, "application/xml+dash");
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetChannelStreamProperties(
+ const kodi::addon::PVRChannel& channel,
+ std::vector<kodi::addon::PVRStreamProperty>& properties)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the signal status of the stream that's currently open.
+ ///
+ /// @param[out] signalStatus The signal status.
+ /// @return @ref PVR_ERROR_NO_ERROR if the signal status has been read successfully, false otherwise.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetHandlesInputStream "SetHandlesInputStream"
+ /// is set to true.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/addon-instance/PVR.h>
+ /// ...
+ ///
+ /// class ATTR_DLL_LOCAL CPVRExample
+ /// : public kodi::addon::CAddonBase,
+ /// public kodi::addon::CInstancePVRClient
+ /// {
+ /// public:
+ /// ...
+ /// PVR_ERROR SignalStatus(PVRSignalStatus &signalStatus) override
+ /// {
+ /// signalStatus.SetAapterName("Example adapter 1");
+ /// signalStatus.SetAdapterStatus("OK");
+ /// signalStatus.SetSignal(0xFFFF); // 100%
+ ///
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// };
+ ///
+ /// ADDONCREATOR(CPVRExample)
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetSignalStatus(int channelUid, kodi::addon::PVRSignalStatus& signalStatus)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the descramble information of the stream that's currently open.
+ ///
+ /// @param[out] descrambleInfo The descramble information.
+ /// @return @ref PVR_ERROR_NO_ERROR if the descramble information has been
+ /// read successfully, false otherwise.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsDescrambleInfo "supportsDescrambleInfo"
+ /// is set to true.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo_Help
+ ///
+ virtual PVR_ERROR GetDescrambleInfo(int channelUid,
+ kodi::addon::PVRDescrambleInfo& descrambleInfo)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Request Kodi to update it's list of channels.
+ ///
+ /// @remarks Only called from addon itself.
+ ///
+ inline void TriggerChannelUpdate()
+ {
+ m_instanceData->toKodi->TriggerChannelUpdate(m_instanceData->toKodi->kodiInstance);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_supportsChannelGroups 3. Channel Groups (optional)
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief <b>Bring in this functions if you have set @ref PVRCapabilities::SetSupportsChannelGroups "supportsChannelGroups"
+ /// to true</b>\n
+ /// This is used to divide available addon channels into groups, which can
+ /// then be selected by the user.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Channel group parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_supportsChannelGroups_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_supportsChannelGroups_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Get the total amount of channel groups on the backend if it supports channel groups.
+ ///
+ /// @param[out] amount The total amount of channel groups on the backend
+ /// @return @ref PVR_ERROR_NO_ERROR if the amount has been fetched successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsChannelGroups "supportsChannelGroups" is set to true.
+ ///
+ virtual PVR_ERROR GetChannelGroupsAmount(int& amount) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get a list of available channel groups on addon
+ ///
+ /// Request the list of all channel groups from the backend if it supports
+ /// channel groups.
+ ///
+ /// @param[in] radio True to get the radio channel groups, false to get the
+ /// TV channel groups.
+ /// @param[out] results List of available groups on addon defined with
+ /// @ref cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup,
+ /// them transferred with
+ /// @ref cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupsResultSet.
+ /// @return @ref PVR_ERROR_NO_ERROR if the list has been fetched successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsChannelGroups "supportsChannelGroups"
+ /// is set to true.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetChannelGroups(bool radio, kodi::addon::PVRChannelGroupsResultSet& groups)
+ /// {
+ /// kodi::addon::PVRChannelGroup group;
+ /// group.SetIsRadio(false);
+ /// group.SetGroupName("My group name");
+ /// group.SetPosition(1);
+ /// ...
+ ///
+ /// // Give it now to Kodi
+ /// results.Add(group);
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetChannelGroups(bool radio, kodi::addon::PVRChannelGroupsResultSet& results)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get a list of members on a group
+ ///
+ /// Request the list of all group members of a group from the backend if it
+ /// supports channel groups.
+ ///
+ /// @param[in] group The group to get the members for.
+ /// @param[out] results List of available group member channels defined with
+ /// @ref cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember,
+ /// them transferred with
+ /// @ref PVRChannelGroupMembersResultSet.
+ /// @return @ref PVR_ERROR_NO_ERROR if the list has been fetched successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember_Help
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsChannelGroups "supportsChannelGroups"
+ /// is set to true.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetChannelGroupMembers(const kodi::addon::PVRChannelGroup& group,
+ /// kodi::addon::PVRChannelGroupMembersResultSet& results)
+ /// {
+ /// for (const auto& myGroup : m_myGroups)
+ /// {
+ /// if (myGroup.strGroupName == group.GetGroupName())
+ /// {
+ /// for (unsigned int iChannelPtr = 0; iChannelPtr < myGroup.members.size(); iChannelPtr++)
+ /// {
+ /// int iId = myGroup.members.at(iChannelPtr) - 1;
+ /// if (iId < 0 || iId > (int)m_channels.size() - 1)
+ /// continue;
+ ///
+ /// PVRDemoChannel &channel = m_channels.at(iId);
+ /// kodi::addon::PVRChannelGroupMember kodiGroupMember;
+ /// kodiGroupMember.SetGroupName(group.GetGroupName());
+ /// kodiGroupMember.SetChannelUniqueId(channel.iUniqueId);
+ /// kodiGroupMember.SetChannelNumber(channel.iChannelNumber);
+ /// kodiGroupMember.SetSubChannelNumber(channel.iSubChannelNumber);
+ ///
+ /// results.Add(kodiGroupMember);
+ /// }
+ /// }
+ /// }
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetChannelGroupMembers(const kodi::addon::PVRChannelGroup& group,
+ kodi::addon::PVRChannelGroupMembersResultSet& results)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Request Kodi to update it's list of channel groups.
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ inline void TriggerChannelGroupsUpdate()
+ {
+ m_instanceData->toKodi->TriggerChannelGroupsUpdate(m_instanceData->toKodi->kodiInstance);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_supportsChannelEdit 4. Channel edit (optional)
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief <b>Bring in this functions if you have set @ref PVRCapabilities::SetSupportsChannelSettings "supportsChannelSettings"
+ /// to true or for @ref OpenDialogChannelScan() set @ref PVRCapabilities::SetSupportsChannelScan "supportsChannelScan"
+ /// to true</b>\n
+ /// The support of this is a pure option and not mandatory.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Channel edit parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_supportsChannelEdit_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_supportsChannelEdit_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Delete a channel from the backend.
+ ///
+ /// @param[in] channel The channel to delete.
+ /// @return @ref PVR_ERROR_NO_ERROR if the channel has been deleted successfully.
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsChannelSettings "supportsChannelSettings"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR DeleteChannel(const kodi::addon::PVRChannel& channel)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Rename a channel on the backend.
+ ///
+ /// @param[in] channel The channel to rename, containing the new channel name.
+ /// @return @ref PVR_ERROR_NO_ERROR if the channel has been renamed successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRChannel_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsChannelSettings "supportsChannelSettings"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR RenameChannel(const kodi::addon::PVRChannel& channel)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Show the channel settings dialog, if supported by the backend.
+ ///
+ /// @param[in] channel The channel to show the dialog for.
+ /// @return @ref PVR_ERROR_NO_ERROR if the dialog has been displayed successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsChannelSettings "supportsChannelSettings" is set to true.
+ /// @note Use @ref cpp_kodi_gui_CWindow "kodi::gui::CWindow" to create dialog for them.
+ ///
+ virtual PVR_ERROR OpenDialogChannelSettings(const kodi::addon::PVRChannel& channel)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Show the dialog to add a channel on the backend, if supported by the backend.
+ ///
+ /// @param[in] channel The channel to add.
+ /// @return @ref PVR_ERROR_NO_ERROR if the channel has been added successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsChannelSettings "supportsChannelSettings" is set to true.
+ /// @note Use @ref cpp_kodi_gui_CWindow "kodi::gui::CWindow" to create dialog for them.
+ ///
+ virtual PVR_ERROR OpenDialogChannelAdd(const kodi::addon::PVRChannel& channel)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Show the channel scan dialog if this backend supports it.
+ ///
+ /// @return @ref PVR_ERROR_NO_ERROR if the dialog was displayed successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsChannelScan "supportsChannelScan" is set to true.
+ /// @note Use @ref cpp_kodi_gui_CWindow "kodi::gui::CWindow" to create dialog for them.
+ ///
+ virtual PVR_ERROR OpenDialogChannelScan() { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Call one of the channel related menu hooks (if supported).
+ ///
+ /// Supported @ref cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook instances have to be added in
+ /// `constructor()`, by calling @ref AddMenuHook() on the callback.
+ ///
+ /// @param[in] menuhook The hook to call.
+ /// @param[in] item The selected channel item for which the hook was called.
+ /// @return @ref PVR_ERROR_NO_ERROR if the hook was called successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help
+ ///
+ virtual PVR_ERROR CallChannelMenuHook(const kodi::addon::PVRMenuhook& menuhook,
+ const kodi::addon::PVRChannel& item)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_EPGTag 4. EPG methods (optional)
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief **PVR EPG methods**\n
+ /// These C ++ class functions of are intended for processing EPG information
+ /// and for giving it to Kodi.
+ ///
+ /// The necessary data is transferred with @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag.
+ ///
+ /// @remarks Only used by Kodi if @ref PVRCapabilities::SetSupportsEPG "supportsEPG"
+ /// is set to true.\n\n
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **EPG parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_EPGTag_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_EPGTag_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Request the EPG for a channel from the backend.
+ ///
+ /// @param[in] channelUid The UID of the channel to get the EPG table for.
+ /// @param[in] start Get events after this time (UTC).
+ /// @param[in] end Get events before this time (UTC).
+ /// @param[out] results List where available EPG information becomes
+ /// transferred with @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag
+ /// and given to Kodi
+ /// @return @ref PVR_ERROR_NO_ERROR if the table has been fetched successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_epg_PVREPGTag_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsEPG "supportsEPG" is set to true.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetEPGForChannel(int channelUid,
+ /// time_t start,
+ /// time_t end,
+ /// kodi::addon::PVREPGTagsResultSet& results)
+ /// {
+ /// // Minimal demo example, in reality bigger, loop to transfer all and to
+ /// // match wanted times.
+ /// kodi::addon::PVREPGTag tag;
+ /// tag.SetUniqueBroadcastId(123);
+ /// tag.SetUniqueChannelId(123);
+ /// tag.SetTitle("My epg entry name");
+ /// tag.SetGenreType(EPG_EVENT_CONTENTMASK_MOVIEDRAMA);
+ /// tag.SetStartTime(1589148283); // Seconds elapsed since 00:00 hours, Jan 1, 1970 UTC
+ /// tag.SetEndTime(1589151913);
+ /// ...
+ ///
+ /// // Give it now to Kodi
+ /// results.Add(tag);
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetEPGForChannel(int channelUid,
+ time_t start,
+ time_t end,
+ kodi::addon::PVREPGTagsResultSet& results)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Check if the given EPG tag can be recorded.
+ ///
+ /// @param[in] tag the @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "epg tag" to check.
+ /// @param[out] isRecordable Set to true if the tag can be recorded.
+ /// @return @ref PVR_ERROR_NO_ERROR if bIsRecordable has been set successfully.
+ ///
+ /// @remarks Optional, it return @ref PVR_ERROR_NOT_IMPLEMENTED by parent to let Kodi decide.
+ ///
+ virtual PVR_ERROR IsEPGTagRecordable(const kodi::addon::PVREPGTag& tag, bool& isRecordable)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Check if the given EPG tag can be played.
+ ///
+ /// @param[in] tag the @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "epg tag" to check.
+ /// @param[out] isPlayable Set to true if the tag can be played.
+ /// @return @ref PVR_ERROR_NO_ERROR if bIsPlayable has been set successfully.
+ ///
+ /// @remarks Required if add-on supports playing epg tags.
+ ///
+ virtual PVR_ERROR IsEPGTagPlayable(const kodi::addon::PVREPGTag& tag, bool& isPlayable)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Retrieve the edit decision list (EDL) of an EPG tag on the backend.
+ ///
+ /// @param[in] tag The @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "epg tag".
+ /// @param[out] edl The function has to write the EDL into this array.
+ /// @return @ref PVR_ERROR_NO_ERROR if the EDL was successfully read or no EDL exists.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsEPGEdl "supportsEPGEdl" is set to true.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsEPGEdl "supportsEPGEdl" is set to true.
+ ///
+ virtual PVR_ERROR GetEPGTagEdl(const kodi::addon::PVREPGTag& tag,
+ std::vector<kodi::addon::PVREDLEntry>& edl)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the stream properties for an epg tag from the backend.
+ ///
+ /// @param[in] tag The @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "epg tag" to get the stream properties for.
+ /// @param[out] properties the properties required to play the stream.
+ /// @return @ref 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 @ref PVR_STREAM_PROPERTY_STREAMURL
+ /// with the URL Kodi should resolve to playback the epg tag.
+ /// It return @ref PVR_ERROR_NOT_IMPLEMENTED from parent if this add-on won't provide this function.
+ ///
+ /// @note The value directly related to inputstream must always begin with the
+ /// name of the associated add-on, e.g. <b>`"inputstream.adaptive.manifest_update_parameter"`</b>.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetEPGTagStreamProperties(const kodi::addon::PVREPGTag& tag,
+ /// std::vector<kodi::addon::PVRStreamProperty>& properties)
+ /// {
+ /// ...
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "inputstream.adaptive");
+ /// properties.emplace_back("inputstream.adaptive.manifest_type", "mpd");
+ /// properties.emplace_back("inputstream.adaptive.manifest_update_parameter", "full");
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_MIMETYPE, "application/xml+dash");
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetEPGTagStreamProperties(
+ const kodi::addon::PVREPGTag& tag, std::vector<kodi::addon::PVRStreamProperty>& properties)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Tell the client the past time frame to use when notifying epg events back to Kodi
+ ///
+ /// The client might push epg events asynchronously to Kodi using the callback function
+ /// @ref EpgEventStateChange. To be able to only push events that are actually of
+ /// interest for Kodi, client needs to know about the epg time frame Kodi uses. Kodi supplies
+ /// the current epg max past time frame value @ref EpgMaxPastDays() when creating the addon
+ /// and calls @ref SetEPGMaxPastDays later whenever Kodi's epg time frame value changes.
+ ///
+ /// @param[in] pastDays number of days before "now". @ref EPG_TIMEFRAME_UNLIMITED means that Kodi
+ /// is interested in all epg events, regardless of event times.
+ /// @return @ref PVR_ERROR_NO_ERROR if new value was successfully set.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsEPG "supportsEPG" is set to true.
+ ///
+ virtual PVR_ERROR SetEPGMaxPastDays(int pastDays) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Tell the client the future time frame to use when notifying epg events back to Kodi
+ ///
+ /// The client might push epg events asynchronously to Kodi using the callback function
+ /// @ref EpgEventStateChange. To be able to only push events that are actually of
+ /// interest for Kodi, client needs to know about the epg time frame Kodi uses. Kodi supplies
+ /// the current epg max future time frame value @ref EpgMaxFutureDays() when creating the addon
+ /// and calls @ref SetEPGMaxFutureDays later whenever Kodi's epg time frame value changes.
+ ///
+ /// @param[in] futureDays number of days from "now". @ref EPG_TIMEFRAME_UNLIMITED means that Kodi
+ /// is interested in all epg events, regardless of event times.
+ /// @return @ref PVR_ERROR_NO_ERROR if new value was successfully set.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsEPG "supportsEPG" is set to true.
+ ///
+ virtual PVR_ERROR SetEPGMaxFutureDays(int futureDays) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Call one of the EPG related menu hooks (if supported).
+ ///
+ /// Supported @ref cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook instances have to be added in
+ /// `constructor()`, by calling @ref AddMenuHook() on the callback.
+ ///
+ /// @param[in] menuhook The hook to call.
+ /// @param[in] tag The selected EPG item for which the hook was called.
+ /// @return @ref PVR_ERROR_NO_ERROR if the hook was called successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help
+ ///
+ virtual PVR_ERROR CallEPGMenuHook(const kodi::addon::PVRMenuhook& menuhook,
+ const kodi::addon::PVREPGTag& tag)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Get the Max past days handled by Kodi.
+ ///
+ /// If > @ref EPG_TIMEFRAME_UNLIMITED, in async epg mode, deliver only events in the
+ /// range from 'end time > now - EpgMaxPastDays()' to 'start time < now + EpgMaxFutureDays().
+ /// @ref EPG_TIMEFRAME_UNLIMITED, notify all events.
+ ///
+ /// @return The Max past days handled by Kodi
+ ///
+ inline int EpgMaxPastDays() const { return m_instanceData->props->iEpgMaxPastDays; }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Get the Max future days handled by Kodi.
+ ///
+ /// If > @ref EPG_TIMEFRAME_UNLIMITED, in async epg mode, deliver only events in the
+ /// range from 'end time > now - EpgMaxPastDays()' to 'start time < now + EpgMaxFutureDays().
+ /// @ref EPG_TIMEFRAME_UNLIMITED, notify all events.
+ ///
+ /// @return The Max future days handled by Kodi
+ ///
+ inline int EpgMaxFutureDays() const { return m_instanceData->props->iEpgMaxFutureDays; }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Schedule an EPG update for the given channel channel.
+ ///
+ /// @param[in] channelUid The unique id of the channel for this add-on
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ inline void TriggerEpgUpdate(unsigned int channelUid)
+ {
+ m_instanceData->toKodi->TriggerEpgUpdate(m_instanceData->toKodi->kodiInstance, channelUid);
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Notify a state change for an EPG event.
+ ///
+ /// @param[in] tag The @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "EPG tag" where have event.
+ /// @param[in] newState The new state.
+ /// - For @ref EPG_EVENT_CREATED and @ref EPG_EVENT_UPDATED, tag must be filled with all available event data, not just a delta.
+ /// - For @ref EPG_EVENT_DELETED, it is sufficient to fill @ref kodi::addon::PVREPGTag::SetUniqueBroadcastId
+ ///
+ /// @remarks Only called from addon itself,
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ ///
+ /// void CMyPVRInstance::MyProcessFunction()
+ /// {
+ /// ...
+ /// kodi::addon::PVREPGTag tag; // Here as mini add, in real it should be a complete tag
+ /// tag.SetUniqueId(123);
+ ///
+ /// // added namespace here not needed to have, only to have more clear for where is
+ /// kodi::addon::CInstancePVRClient::EpgEventStateChange(tag, EPG_EVENT_UPDATED);
+ /// ...
+ /// }
+ ///
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ inline void EpgEventStateChange(kodi::addon::PVREPGTag& tag, EPG_EVENT_STATE newState)
+ {
+ m_instanceData->toKodi->EpgEventStateChange(m_instanceData->toKodi->kodiInstance, tag.GetTag(),
+ newState);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Recordings 5. Recordings (optional)
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief **PVR recording methods**\n
+ /// To transfer available recordings of the PVR backend and to allow possible
+ /// playback.
+ ///
+ /// @remarks Only used by Kodi if @ref PVRCapabilities::SetSupportsRecordings "supportsRecordings"
+ /// is set to true.\n\n
+ /// If a recordings changes after the initial import, or if a new one was added,
+ /// then the add-on should call @ref TriggerRecordingUpdate().
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Recordings parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Recordings_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Recordings_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief To get amount of recording present on backend
+ ///
+ /// @param[in] deleted if set return deleted recording (called if
+ /// @ref PVRCapabilities::SetSupportsRecordingsUndelete "supportsRecordingsUndelete"
+ /// set to true)
+ /// @param[out] amount The total amount of recordings on the backend
+ /// @return @ref PVR_ERROR_NO_ERROR if the amount has been fetched successfully.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings "supportsRecordings" is set to true.
+ ///
+ virtual PVR_ERROR GetRecordingsAmount(bool deleted, int& amount)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Request the list of all recordings from the backend, if supported.
+ ///
+ /// Recording entries are added to Kodi by calling TransferRecordingEntry() on the callback.
+ ///
+ /// @param[in] deleted if set return deleted recording (called if
+ /// @ref PVRCapabilities::SetSupportsRecordingsUndelete "supportsRecordingsUndelete"
+ /// set to true)
+ /// @param[out] results List of available recordings with @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ /// becomes transferred with @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecordingsResultSet
+ /// and given to Kodi
+ /// @return @ref PVR_ERROR_NO_ERROR if the recordings have been fetched successfully.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings "supportsRecordings"
+ /// is set to true.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Recording_PVRRecording_Help
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetRecordings(bool deleted, kodi::addon::PVRRecordingsResultSet& results)
+ /// {
+ /// // Minimal demo example, in reality bigger and loop to transfer all
+ /// kodi::addon::PVRRecording recording;
+ /// recording.SetRecordingId(123);
+ /// recording.SetTitle("My recording name");
+ /// ...
+ ///
+ /// // Give it now to Kodi
+ /// results.Add(recording);
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetRecordings(bool deleted, kodi::addon::PVRRecordingsResultSet& results)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Delete a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording to delete.
+ /// @return @ref PVR_ERROR_NO_ERROR if the recording has been deleted successfully.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings "supportsRecordings"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR DeleteRecording(const kodi::addon::PVRRecording& recording)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Undelete a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording to undelete.
+ /// @return @ref PVR_ERROR_NO_ERROR if the recording has been undeleted successfully.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordingsUndelete "supportsRecordingsUndelete"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR UndeleteRecording(const kodi::addon::PVRRecording& recording)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Delete all recordings permanent which in the deleted folder on the backend.
+ ///
+ /// @return @ref PVR_ERROR_NO_ERROR if the recordings has been deleted successfully.
+ ///
+ virtual PVR_ERROR DeleteAllRecordingsFromTrash() { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Rename a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ /// to rename, containing the new name.
+ /// @return @ref PVR_ERROR_NO_ERROR if the recording has been renamed successfully.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings "supportsRecordings"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR RenameRecording(const kodi::addon::PVRRecording& recording)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the lifetime of a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ /// to change the lifetime for. recording.iLifetime
+ /// contains the new lieftime value.
+ /// @return @ref PVR_ERROR_NO_ERROR if the recording's lifetime has been set
+ /// successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsRecordingsLifetimeChange "supportsRecordingsLifetimeChange"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR SetRecordingLifetime(const kodi::addon::PVRRecording& recording)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the play count of a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ /// to change the play count.
+ /// @param[in] count Play count.
+ /// @return @ref PVR_ERROR_NO_ERROR if the recording's play count has been set
+ /// successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsRecordingPlayCount "supportsRecordingPlayCount"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR SetRecordingPlayCount(const kodi::addon::PVRRecording& recording, int count)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the last watched position of a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording.
+ /// @param[in] lastplayedposition The last watched position in seconds
+ /// @return @ref PVR_ERROR_NO_ERROR if the position has been stored successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsLastPlayedPosition "supportsLastPlayedPosition"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR SetRecordingLastPlayedPosition(const kodi::addon::PVRRecording& recording,
+ int lastplayedposition)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Retrieve the last watched position of a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording.
+ /// @param[out] position The last watched position in seconds
+ /// @return @ref PVR_ERROR_NO_ERROR if the amount has been fetched successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsRecordingPlayCount "supportsRecordingPlayCount"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR GetRecordingLastPlayedPosition(const kodi::addon::PVRRecording& recording,
+ int& position)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Retrieve the edit decision list (EDL) of a recording on the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording.
+ /// @param[out] edl The function has to write the EDL into this array.
+ /// @return @ref PVR_ERROR_NO_ERROR if the EDL was successfully read or no EDL exists.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsRecordingEdl "supportsRecordingEdl"
+ /// is set to true.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry_Help
+ ///
+ virtual PVR_ERROR GetRecordingEdl(const kodi::addon::PVRRecording& recording,
+ std::vector<kodi::addon::PVREDLEntry>& edl)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Retrieve the size of a recording on the backend.
+ ///
+ /// @param[in] recording The recording to get the size in bytes for.
+ /// @param[out] size The size in bytes of the recording
+ /// @return @ref PVR_ERROR_NO_ERROR if the recording's size has been set successfully.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsRecordingSize "supportsRecordingSize"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR GetRecordingSize(const kodi::addon::PVRRecording& recording, int64_t& size)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the stream properties for a recording from the backend.
+ ///
+ /// @param[in] recording The @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ /// to get the stream properties for.
+ /// @param[out] properties The properties required to play the stream.
+ /// @return @ref PVR_ERROR_NO_ERROR if the stream is available.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsRecordings "supportsRecordings"
+ /// is set to true and the add-on does not implement recording stream functions
+ /// (@ref OpenRecordedStream, ...).\n
+ /// In this case your implementation must fill the property @ref PVR_STREAM_PROPERTY_STREAMURL
+ /// with the URL Kodi should resolve to playback the recording.
+ ///
+ /// @note The value directly related to inputstream must always begin with the
+ /// name of the associated add-on, e.g. <b>`"inputstream.adaptive.manifest_update_parameter"`</b>.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetRecordingStreamProperties(const kodi::addon::PVRRecording& recording,
+ /// std::vector<kodi::addon::PVRStreamProperty>& properties)
+ /// {
+ /// ...
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "inputstream.adaptive");
+ /// properties.emplace_back("inputstream.adaptive.manifest_type", "mpd");
+ /// properties.emplace_back("inputstream.adaptive.manifest_update_parameter", "full");
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_MIMETYPE, "application/xml+dash");
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetRecordingStreamProperties(
+ const kodi::addon::PVRRecording& recording,
+ std::vector<kodi::addon::PVRStreamProperty>& properties)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief Call one of the recording related menu hooks (if supported).
+ ///
+ /// Supported @ref cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook instances have to be added in
+ /// `constructor()`, by calling @ref AddMenuHook() on the callback.
+ ///
+ /// @param[in] menuhook The hook to call.
+ /// @param[in] item The selected recording item for which the hook was called.
+ /// @return @ref PVR_ERROR_NO_ERROR if the hook was called successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help
+ ///
+ virtual PVR_ERROR CallRecordingMenuHook(const kodi::addon::PVRMenuhook& menuhook,
+ const kodi::addon::PVRRecording& item)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Display a notification in Kodi that a recording started or stopped on the
+ /// server.
+ ///
+ /// @param[in] recordingName The name of the recording to display
+ /// @param[in] fileName The filename of the recording
+ /// @param[in] on True when recording started, false when it stopped
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ inline void RecordingNotification(const std::string& recordingName,
+ const std::string& fileName,
+ bool on)
+ {
+ m_instanceData->toKodi->RecordingNotification(m_instanceData->toKodi->kodiInstance,
+ recordingName.c_str(), fileName.c_str(), on);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Request Kodi to update it's list of recordings.
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ inline void TriggerRecordingUpdate()
+ {
+ m_instanceData->toKodi->TriggerRecordingUpdate(m_instanceData->toKodi->kodiInstance);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Timers 6. Timers (optional)
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief **PVR timer methods**\n
+ /// For editing and displaying timed work, such as video recording.
+ ///
+ /// @remarks Only used by Kodi if @ref PVRCapabilities::SetSupportsTimers "supportsTimers"
+ /// is set to true.\n\n
+ /// If a timer changes after the initial import, or if a new one was added,
+ /// then the add-on should call @ref TriggerTimerUpdate().
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Timer parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Timers_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Timers_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Retrieve the timer types supported by the backend.
+ ///
+ /// @param[out] types The function has to write the definition of the
+ /// @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType types
+ /// into this array.
+ /// @return @ref PVR_ERROR_NO_ERROR if the types were successfully written to
+ /// the array.
+ ///
+ /// @note Maximal 32 entries are allowed inside.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType_Help
+ ///
+ virtual PVR_ERROR GetTimerTypes(std::vector<kodi::addon::PVRTimerType>& types)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief To get total amount of timers on the backend or -1 on error.
+ ///
+ /// @param[out] amount The total amount of timers on the backend
+ /// @return @ref PVR_ERROR_NO_ERROR if the amount has been fetched successfully.
+ ///
+ /// @note Required to use if @ref PVRCapabilities::SetSupportsTimers "supportsTimers"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR GetTimersAmount(int& amount) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Request the list of all timers from the backend if supported.
+ ///
+ /// @param[out] results List of available timers with @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimer
+ /// becomes transferred with @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimersResultSet
+ /// and given to Kodi
+ /// @return @ref PVR_ERROR_NO_ERROR if the list has been fetched successfully.
+ ///
+ /// @note Required to use if @ref PVRCapabilities::SetSupportsTimers "supportsTimers"
+ /// is set to true.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Timer_PVRTimer_Help
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// PVR_ERROR CMyPVRInstance::GetTimers(kodi::addon::PVRTimersResultSet& results)
+ /// {
+ /// // Minimal demo example, in reality bigger and loop to transfer all
+ /// kodi::addon::PVRTimer timer;
+ /// timer.SetClientIndex(123);
+ /// timer.SetState(PVR_TIMER_STATE_SCHEDULED);
+ /// timer.SetTitle("My timer name");
+ /// ...
+ ///
+ /// // Give it now to Kodi
+ /// results.Add(timer);
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual PVR_ERROR GetTimers(kodi::addon::PVRTimersResultSet& results)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Add a timer on the backend.
+ ///
+ /// @param[in] timer The timer to add.
+ /// @return @ref PVR_ERROR_NO_ERROR if the timer has been added successfully.
+ ///
+ /// @note Required to use if @ref PVRCapabilities::SetSupportsTimers "supportsTimers"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR AddTimer(const kodi::addon::PVRTimer& timer)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Delete a timer on the backend.
+ ///
+ /// @param[in] timer The timer to delete.
+ /// @param[in] forceDelete Set to true to delete a timer that is currently
+ /// recording a program.
+ /// @return @ref PVR_ERROR_NO_ERROR if the timer has been deleted successfully.
+ ///
+ /// @note Required to use if @ref PVRCapabilities::SetSupportsTimers "supportsTimers"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR DeleteTimer(const kodi::addon::PVRTimer& timer, bool forceDelete)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Update the timer information on the backend.
+ ///
+ /// @param[in] timer The timer to update.
+ /// @return @ref PVR_ERROR_NO_ERROR if the timer has been updated successfully.
+ ///
+ /// @note Required to use if @ref PVRCapabilities::SetSupportsTimers "supportsTimers"
+ /// is set to true.
+ ///
+ virtual PVR_ERROR UpdateTimer(const kodi::addon::PVRTimer& timer)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Call one of the timer related menu hooks (if supported).
+ ///
+ /// Supported @ref cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook instances have
+ /// to be added in `constructor()`, by calling @ref AddMenuHook() on the
+ /// callback.
+ ///
+ /// @param[in] menuhook The hook to call.
+ /// @param[in] item The selected timer item for which the hook was called.
+ /// @return @ref PVR_ERROR_NO_ERROR if the hook was called successfully.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help
+ ///
+ virtual PVR_ERROR CallTimerMenuHook(const kodi::addon::PVRMenuhook& menuhook,
+ const kodi::addon::PVRTimer& item)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Request Kodi to update it's list of timers.
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ inline void TriggerTimerUpdate()
+ {
+ m_instanceData->toKodi->TriggerTimerUpdate(m_instanceData->toKodi->kodiInstance);
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_PowerManagement 7. Power management events (optional)
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief **Used to notify the pvr addon for power management events**\n
+ /// Used to allow any energy savings.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Power management events in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_PowerManagement_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_PowerManagement_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief To notify addon about system sleep
+ ///
+ /// @return @ref PVR_ERROR_NO_ERROR If successfully done.
+ ///
+ virtual PVR_ERROR OnSystemSleep() { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief To notify addon about system wake up
+ ///
+ /// @return @ref PVR_ERROR_NO_ERROR If successfully done.
+ ///
+ virtual PVR_ERROR OnSystemWake() { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief To notify addon power saving on system is activated
+ ///
+ /// @return @ref PVR_ERROR_NO_ERROR If successfully done.
+ ///
+ virtual PVR_ERROR OnPowerSavingActivated() { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief To notify addon power saving on system is deactivated
+ ///
+ /// @return @ref PVR_ERROR_NO_ERROR If successfully done.
+ ///
+ virtual PVR_ERROR OnPowerSavingDeactivated() { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Streams 8. Inputstream
+ /// @ingroup cpp_kodi_addon_pvr
+ /// @brief **PVR Inputstream**\n
+ /// This includes functions that are used in the PVR inputstream.
+ ///
+ /// @warning The parts here will be removed in the future and replaced by the
+ /// separate @ref cpp_kodi_addon_inputstream "inputstream addon instance".
+ /// If there is already a possibility, new addons should do it via the
+ /// inputstream instance.
+ ///
+ ///@{
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Streams_TV 8.1. TV stream
+ /// @ingroup cpp_kodi_addon_pvr_Streams
+ /// @brief **PVR TV stream**\n
+ /// Stream processing regarding live TV.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **TV stream parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Streams_TV_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Streams_TV_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Open a live stream on the backend.
+ ///
+ /// @param[in] channel The channel to stream.
+ /// @return True if the stream has been opened successfully, false otherwise.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRChannel_Help
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetHandlesInputStream() or
+ /// @ref PVRCapabilities::SetHandlesDemuxing() is set to true.
+ /// @ref CloseLiveStream() will always be called by Kodi prior to calling this
+ /// function.
+ ///
+ virtual bool OpenLiveStream(const kodi::addon::PVRChannel& channel) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Close an open live stream.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetHandlesInputStream() or
+ /// @ref PVRCapabilities::SetHandlesDemuxing() is set to true.
+ ///
+ virtual void CloseLiveStream() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Read from an open live stream.
+ ///
+ /// @param[in] pBuffer The buffer to store the data in.
+ /// @param[in] iBufferSize The amount of bytes to read.
+ /// @return The amount of bytes that were actually read from the stream.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetHandlesInputStream() is set
+ /// to true.
+ ///
+ virtual int ReadLiveStream(unsigned char* buffer, unsigned int size) { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Seek in a live stream on a backend that supports timeshifting.
+ ///
+ /// @param[in] position The position to seek to.
+ /// @param[in] whence [optional] offset relative to
+ /// You can set the value of whence to one of three things:
+ /// | Value | int | Description |
+ /// |:--------:|:---:|:----------------------------------------------------|
+ /// | SEEK_SET | 0 | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
+ /// | SEEK_CUR | 1 | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
+ /// | SEEK_END | 2 | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
+ ///
+ /// @return The new position.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetHandlesInputStream()
+ /// is set to true.
+ ///
+ virtual int64_t SeekLiveStream(int64_t position, int whence) { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Obtain the length of a live stream.
+ ///
+ /// @return The total length of the stream that's currently being read.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetHandlesInputStream()
+ /// is set to true.
+ ///
+ virtual int64_t LengthLiveStream() { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Streams_TV_Demux 8.1.1. Stream demuxing
+ /// @ingroup cpp_kodi_addon_pvr_Streams_TV
+ /// @brief **PVR stream demuxing**\n
+ /// Read TV streams with own demux within addon.
+ ///
+ /// This is only on Live TV streams and only if @ref PVRCapabilities::SetHandlesDemuxing()
+ /// has been set to "true".
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Stream demuxing parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Streams_TV_Demux_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Streams_TV_Demux_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Get the stream properties of the stream that's currently being read.
+ ///
+ /// @param[in] properties The properties of the currently playing stream.
+ /// @return @ref PVR_ERROR_NO_ERROR if the properties have been fetched successfully.
+ ///
+ /// @remarks Required, and only used if addon has its own demuxer.
+ ///
+ virtual PVR_ERROR GetStreamProperties(std::vector<kodi::addon::PVRStreamProperties>& properties)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Read the next packet from the demultiplexer, if there is one.
+ ///
+ /// @return The next packet.
+ /// If there is no next packet, then the add-on should return the packet
+ /// created by calling @ref AllocateDemuxPacket(0) on the callback.
+ /// If the stream changed and Kodi's player needs to be reinitialised, then,
+ /// the add-on should call @ref AllocateDemuxPacket(0) on the callback, and set
+ /// the streamid to @ref DMX_SPECIALID_STREAMCHANGE and return the value.
+ /// The add-on should return `nullptr` if an error occurred.
+ ///
+ /// @remarks Required, and only used if addon has its own demuxer.
+ /// Return `nullptr` if this add-on won't provide this function.
+ ///
+ virtual DEMUX_PACKET* DemuxRead() { return nullptr; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Reset the demultiplexer in the add-on.
+ ///
+ /// @remarks Required, and only used if addon has its own demuxer.
+ ///
+ virtual void DemuxReset() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Abort the demultiplexer thread in the add-on.
+ ///
+ /// @remarks Required, and only used if addon has its own demuxer.
+ ///
+ virtual void DemuxAbort() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Flush all data that's currently in the demultiplexer buffer in the
+ /// add-on.
+ ///
+ /// @remarks Required, and only used if addon has its own demuxer.
+ ///
+ virtual void DemuxFlush() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify the pvr addon/demuxer that Kodi wishes to change playback
+ /// speed.
+ ///
+ /// @param[in] speed The requested playback speed
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ ///
+ virtual void SetSpeed(int speed) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify the pvr addon/demuxer that Kodi wishes to fill demux queue.
+ ///
+ /// @param[in] mode The requested filling mode
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ ///
+ virtual void FillBuffer(bool mode) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify the pvr addon/demuxer that Kodi wishes to seek the stream by
+ /// time.
+ ///
+ /// @param[in] time The absolute time since stream start
+ /// @param[in] backwards True to seek to keyframe BEFORE time, else AFTER
+ /// @param[in] startpts can be updated to point to where display should start
+ /// @return True if the seek operation was possible
+ ///
+ /// @remarks Optional, and only used if addon has its own demuxer.
+ /// Return False if this add-on won't provide this function.
+ ///
+ virtual bool SeekTime(double time, bool backwards, double& startpts) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Get the codec id used by Kodi.
+ ///
+ /// @param[in] codecName The name of the codec
+ /// @return The codec_id, or a codec_id with 0 values when not supported
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ inline PVRCodec GetCodecByName(const std::string& codecName) const
+ {
+ return PVRCodec(m_instanceData->toKodi->GetCodecByName(m_instanceData->toKodi->kodiInstance,
+ codecName.c_str()));
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Allocate a demux packet. Free with @ref FreeDemuxPacket().
+ ///
+ /// @param[in] iDataSize The size of the data that will go into the packet
+ /// @return The allocated packet
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ inline DEMUX_PACKET* AllocateDemuxPacket(int iDataSize)
+ {
+ return m_instanceData->toKodi->AllocateDemuxPacket(m_instanceData->toKodi->kodiInstance,
+ iDataSize);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Free a packet that was allocated with @ref AllocateDemuxPacket().
+ ///
+ /// @param[in] pPacket The packet to free
+ ///
+ /// @remarks Only called from addon itself.
+ ///
+ inline void FreeDemuxPacket(DEMUX_PACKET* pPacket)
+ {
+ m_instanceData->toKodi->FreeDemuxPacket(m_instanceData->toKodi->kodiInstance, pPacket);
+ }
+ //----------------------------------------------------------------------------
+ ///@}
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Streams_Recording 8.2. Recording stream
+ /// @ingroup cpp_kodi_addon_pvr_Streams
+ /// @brief **PVR Recording stream**\n
+ /// Stream processing regarding recordings.
+ ///
+ /// @note Demuxing is not possible with the recordings.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Recording stream parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Streams_Recording_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Streams_Recording_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Open a stream to a recording on the backend.
+ ///
+ /// @param[in] recording The recording to open.
+ /// @return True if the stream has been opened successfully, false otherwise.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings()
+ /// is set to true. @ref CloseRecordedStream() will always be called by Kodi
+ /// prior to calling this function.
+ ///
+ virtual bool OpenRecordedStream(const kodi::addon::PVRRecording& recording) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Close an open stream from a recording.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings()
+ /// is set to true.
+ ///
+ virtual void CloseRecordedStream() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Read from a recording.
+ ///
+ /// @param[in] buffer The buffer to store the data in.
+ /// @param[in] size The amount of bytes to read.
+ /// @return The amount of bytes that were actually read from the stream.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings()
+ /// is set to true.
+ ///
+ virtual int ReadRecordedStream(unsigned char* buffer, unsigned int size) { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Seek in a recorded stream.
+ ///
+ /// @param[in] position The position to seek to.
+ /// @param[in] whence [optional] offset relative to
+ /// You can set the value of whence to one of three things:
+ /// | Value | int | Description |
+ /// |:--------:|:---:|:----------------------------------------------------|
+ /// | SEEK_SET | 0 | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
+ /// | SEEK_CUR | 1 | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
+ /// | SEEK_END | 2 | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
+ ///
+ /// @return The new position.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings()
+ /// is set to true.
+ ///
+ virtual int64_t SeekRecordedStream(int64_t position, int whence) { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Obtain the length of a recorded stream.
+ ///
+ /// @return The total length of the stream that's currently being read.
+ ///
+ /// @remarks Optional, and only used if @ref PVRCapabilities::SetSupportsRecordings()
+ /// is true (=> @ref ReadRecordedStream).
+ ///
+ virtual int64_t LengthRecordedStream() { return 0; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Streams_Various 8.3. Various functions
+ /// @ingroup cpp_kodi_addon_pvr_Streams
+ /// @brief **Various other PVR stream related functions**\n
+ /// These apply to all other groups in inputstream and are therefore declared
+ /// as several.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Various stream parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Streams_Various_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_pvr_Streams_Various_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ ///
+ /// @brief Check if the backend support pausing the currently playing stream.
+ ///
+ /// This will enable/disable the pause button in Kodi based on the return
+ /// value.
+ ///
+ /// @return false if the PVR addon/backend does not support pausing, true if
+ /// possible
+ ///
+ virtual bool CanPauseStream() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ ///
+ /// @brief Check if the backend supports seeking for the currently playing
+ /// stream.
+ ///
+ /// This will enable/disable the rewind/forward buttons in Kodi based on the
+ /// return value.
+ ///
+ /// @return false if the PVR addon/backend does not support seeking, true if
+ /// possible
+ ///
+ virtual bool CanSeekStream() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ ///
+ /// @brief Notify the pvr addon that Kodi (un)paused the currently playing
+ /// stream.
+ ///
+ /// @param[in] paused To inform by `true` is paused and with `false` playing
+ ///
+ virtual void PauseStream(bool paused) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ ///
+ /// @brief Check for real-time streaming.
+ ///
+ /// @return true if current stream is real-time
+ ///
+ virtual bool IsRealTimeStream() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ ///
+ /// @brief Get stream times.
+ ///
+ /// @param[out] times A pointer to the data to be filled by the implementation.
+ /// @return @ref PVR_ERROR_NO_ERROR on success.
+ ///
+ virtual PVR_ERROR GetStreamTimes(kodi::addon::PVRStreamTimes& times)
+ {
+ return PVR_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ ///
+ /// @brief Obtain the chunk size to use when reading streams.
+ ///
+ /// @param[out] chunksize must be filled with the chunk size in bytes.
+ /// @return @ref PVR_ERROR_NO_ERROR if the chunk size has been fetched successfully.
+ ///
+ /// @remarks Optional, and only used if not reading from demuxer (=> @ref DemuxRead) and
+ /// @ref PVRCapabilities::SetSupportsRecordings() is true (=> @ref ReadRecordedStream) or
+ /// @ref PVRCapabilities::SetHandlesInputStream() is true (=> @ref ReadLiveStream).
+ ///
+ virtual PVR_ERROR GetStreamReadChunkSize(int& chunksize) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->GetCapabilities = ADDON_GetCapabilities;
+ instance->pvr->toAddon->GetConnectionString = ADDON_GetConnectionString;
+ instance->pvr->toAddon->GetBackendName = ADDON_GetBackendName;
+ instance->pvr->toAddon->GetBackendVersion = ADDON_GetBackendVersion;
+ instance->pvr->toAddon->GetBackendHostname = ADDON_GetBackendHostname;
+ instance->pvr->toAddon->GetDriveSpace = ADDON_GetDriveSpace;
+ instance->pvr->toAddon->CallSettingsMenuHook = ADDON_CallSettingsMenuHook;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->GetChannelsAmount = ADDON_GetChannelsAmount;
+ instance->pvr->toAddon->GetChannels = ADDON_GetChannels;
+ instance->pvr->toAddon->GetChannelStreamProperties = ADDON_GetChannelStreamProperties;
+ instance->pvr->toAddon->GetSignalStatus = ADDON_GetSignalStatus;
+ instance->pvr->toAddon->GetDescrambleInfo = ADDON_GetDescrambleInfo;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->GetProvidersAmount = ADDON_GetProvidersAmount;
+ instance->pvr->toAddon->GetProviders = ADDON_GetProviders;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->GetChannelGroupsAmount = ADDON_GetChannelGroupsAmount;
+ instance->pvr->toAddon->GetChannelGroups = ADDON_GetChannelGroups;
+ instance->pvr->toAddon->GetChannelGroupMembers = ADDON_GetChannelGroupMembers;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->DeleteChannel = ADDON_DeleteChannel;
+ instance->pvr->toAddon->RenameChannel = ADDON_RenameChannel;
+ instance->pvr->toAddon->OpenDialogChannelSettings = ADDON_OpenDialogChannelSettings;
+ instance->pvr->toAddon->OpenDialogChannelAdd = ADDON_OpenDialogChannelAdd;
+ instance->pvr->toAddon->OpenDialogChannelScan = ADDON_OpenDialogChannelScan;
+ instance->pvr->toAddon->CallChannelMenuHook = ADDON_CallChannelMenuHook;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->GetEPGForChannel = ADDON_GetEPGForChannel;
+ instance->pvr->toAddon->IsEPGTagRecordable = ADDON_IsEPGTagRecordable;
+ instance->pvr->toAddon->IsEPGTagPlayable = ADDON_IsEPGTagPlayable;
+ instance->pvr->toAddon->GetEPGTagEdl = ADDON_GetEPGTagEdl;
+ instance->pvr->toAddon->GetEPGTagStreamProperties = ADDON_GetEPGTagStreamProperties;
+ instance->pvr->toAddon->SetEPGMaxPastDays = ADDON_SetEPGMaxPastDays;
+ instance->pvr->toAddon->SetEPGMaxFutureDays = ADDON_SetEPGMaxFutureDays;
+ instance->pvr->toAddon->CallEPGMenuHook = ADDON_CallEPGMenuHook;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->GetRecordingsAmount = ADDON_GetRecordingsAmount;
+ instance->pvr->toAddon->GetRecordings = ADDON_GetRecordings;
+ instance->pvr->toAddon->DeleteRecording = ADDON_DeleteRecording;
+ instance->pvr->toAddon->UndeleteRecording = ADDON_UndeleteRecording;
+ instance->pvr->toAddon->DeleteAllRecordingsFromTrash = ADDON_DeleteAllRecordingsFromTrash;
+ instance->pvr->toAddon->RenameRecording = ADDON_RenameRecording;
+ instance->pvr->toAddon->SetRecordingLifetime = ADDON_SetRecordingLifetime;
+ instance->pvr->toAddon->SetRecordingPlayCount = ADDON_SetRecordingPlayCount;
+ instance->pvr->toAddon->SetRecordingLastPlayedPosition = ADDON_SetRecordingLastPlayedPosition;
+ instance->pvr->toAddon->GetRecordingLastPlayedPosition = ADDON_GetRecordingLastPlayedPosition;
+ instance->pvr->toAddon->GetRecordingEdl = ADDON_GetRecordingEdl;
+ instance->pvr->toAddon->GetRecordingSize = ADDON_GetRecordingSize;
+ instance->pvr->toAddon->GetRecordingStreamProperties = ADDON_GetRecordingStreamProperties;
+ instance->pvr->toAddon->CallRecordingMenuHook = ADDON_CallRecordingMenuHook;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->GetTimerTypes = ADDON_GetTimerTypes;
+ instance->pvr->toAddon->GetTimersAmount = ADDON_GetTimersAmount;
+ instance->pvr->toAddon->GetTimers = ADDON_GetTimers;
+ instance->pvr->toAddon->AddTimer = ADDON_AddTimer;
+ instance->pvr->toAddon->DeleteTimer = ADDON_DeleteTimer;
+ instance->pvr->toAddon->UpdateTimer = ADDON_UpdateTimer;
+ instance->pvr->toAddon->CallTimerMenuHook = ADDON_CallTimerMenuHook;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->OnSystemSleep = ADDON_OnSystemSleep;
+ instance->pvr->toAddon->OnSystemWake = ADDON_OnSystemWake;
+ instance->pvr->toAddon->OnPowerSavingActivated = ADDON_OnPowerSavingActivated;
+ instance->pvr->toAddon->OnPowerSavingDeactivated = ADDON_OnPowerSavingDeactivated;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->OpenLiveStream = ADDON_OpenLiveStream;
+ instance->pvr->toAddon->CloseLiveStream = ADDON_CloseLiveStream;
+ instance->pvr->toAddon->ReadLiveStream = ADDON_ReadLiveStream;
+ instance->pvr->toAddon->SeekLiveStream = ADDON_SeekLiveStream;
+ instance->pvr->toAddon->LengthLiveStream = ADDON_LengthLiveStream;
+ instance->pvr->toAddon->GetStreamProperties = ADDON_GetStreamProperties;
+ instance->pvr->toAddon->GetStreamReadChunkSize = ADDON_GetStreamReadChunkSize;
+ instance->pvr->toAddon->IsRealTimeStream = ADDON_IsRealTimeStream;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->OpenRecordedStream = ADDON_OpenRecordedStream;
+ instance->pvr->toAddon->CloseRecordedStream = ADDON_CloseRecordedStream;
+ instance->pvr->toAddon->ReadRecordedStream = ADDON_ReadRecordedStream;
+ instance->pvr->toAddon->SeekRecordedStream = ADDON_SeekRecordedStream;
+ instance->pvr->toAddon->LengthRecordedStream = ADDON_LengthRecordedStream;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->DemuxReset = ADDON_DemuxReset;
+ instance->pvr->toAddon->DemuxAbort = ADDON_DemuxAbort;
+ instance->pvr->toAddon->DemuxFlush = ADDON_DemuxFlush;
+ instance->pvr->toAddon->DemuxRead = ADDON_DemuxRead;
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ instance->pvr->toAddon->CanPauseStream = ADDON_CanPauseStream;
+ instance->pvr->toAddon->PauseStream = ADDON_PauseStream;
+ instance->pvr->toAddon->CanSeekStream = ADDON_CanSeekStream;
+ instance->pvr->toAddon->SeekTime = ADDON_SeekTime;
+ instance->pvr->toAddon->SetSpeed = ADDON_SetSpeed;
+ instance->pvr->toAddon->FillBuffer = ADDON_FillBuffer;
+ instance->pvr->toAddon->GetStreamTimes = ADDON_GetStreamTimes;
+
+ m_instanceData = instance->pvr;
+ m_instanceData->toAddon->addonInstance = this;
+ }
+
+ inline static PVR_ERROR ADDON_GetCapabilities(const AddonInstance_PVR* instance,
+ PVR_ADDON_CAPABILITIES* capabilities)
+ {
+ PVRCapabilities cppCapabilities(capabilities);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetCapabilities(cppCapabilities);
+ }
+
+ inline static PVR_ERROR ADDON_GetBackendName(const AddonInstance_PVR* instance,
+ char* str,
+ int memSize)
+ {
+ std::string backendName;
+ PVR_ERROR err = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetBackendName(backendName);
+ if (err == PVR_ERROR_NO_ERROR)
+ strncpy(str, backendName.c_str(), memSize);
+ return err;
+ }
+
+ inline static PVR_ERROR ADDON_GetBackendVersion(const AddonInstance_PVR* instance,
+ char* str,
+ int memSize)
+ {
+ std::string backendVersion;
+ PVR_ERROR err = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetBackendVersion(backendVersion);
+ if (err == PVR_ERROR_NO_ERROR)
+ strncpy(str, backendVersion.c_str(), memSize);
+ return err;
+ }
+
+ inline static PVR_ERROR ADDON_GetBackendHostname(const AddonInstance_PVR* instance,
+ char* str,
+ int memSize)
+ {
+ std::string backendHostname;
+ PVR_ERROR err = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetBackendHostname(backendHostname);
+ if (err == PVR_ERROR_NO_ERROR)
+ strncpy(str, backendHostname.c_str(), memSize);
+ return err;
+ }
+
+ inline static PVR_ERROR ADDON_GetConnectionString(const AddonInstance_PVR* instance,
+ char* str,
+ int memSize)
+ {
+ std::string connectionString;
+ PVR_ERROR err = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetConnectionString(connectionString);
+ if (err == PVR_ERROR_NO_ERROR)
+ strncpy(str, connectionString.c_str(), memSize);
+ return err;
+ }
+
+ inline static PVR_ERROR ADDON_GetDriveSpace(const AddonInstance_PVR* instance,
+ uint64_t* total,
+ uint64_t* used)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetDriveSpace(*total, *used);
+ }
+
+ inline static PVR_ERROR ADDON_CallSettingsMenuHook(const AddonInstance_PVR* instance,
+ const PVR_MENUHOOK* menuhook)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->CallSettingsMenuHook(menuhook);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ inline static PVR_ERROR ADDON_GetChannelsAmount(const AddonInstance_PVR* instance, int* amount)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetChannelsAmount(*amount);
+ }
+
+ inline static PVR_ERROR ADDON_GetChannels(const AddonInstance_PVR* instance,
+ PVR_HANDLE handle,
+ bool radio)
+ {
+ PVRChannelsResultSet result(instance, handle);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetChannels(radio, result);
+ }
+
+ inline static PVR_ERROR ADDON_GetChannelStreamProperties(const AddonInstance_PVR* instance,
+ const PVR_CHANNEL* channel,
+ PVR_NAMED_VALUE* properties,
+ unsigned int* propertiesCount)
+ {
+ *propertiesCount = 0;
+ std::vector<PVRStreamProperty> propertiesList;
+ PVR_ERROR error = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetChannelStreamProperties(channel, propertiesList);
+ if (error == PVR_ERROR_NO_ERROR)
+ {
+ for (const auto& property : propertiesList)
+ {
+ strncpy(properties[*propertiesCount].strName, property.GetCStructure()->strName,
+ sizeof(properties[*propertiesCount].strName) - 1);
+ strncpy(properties[*propertiesCount].strValue, property.GetCStructure()->strValue,
+ sizeof(properties[*propertiesCount].strValue) - 1);
+ ++*propertiesCount;
+ if (*propertiesCount > STREAM_MAX_PROPERTY_COUNT)
+ break;
+ }
+ }
+ return error;
+ }
+
+ inline static PVR_ERROR ADDON_GetSignalStatus(const AddonInstance_PVR* instance,
+ int channelUid,
+ PVR_SIGNAL_STATUS* signalStatus)
+ {
+ PVRSignalStatus cppSignalStatus(signalStatus);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetSignalStatus(channelUid, cppSignalStatus);
+ }
+
+ inline static PVR_ERROR ADDON_GetDescrambleInfo(const AddonInstance_PVR* instance,
+ int channelUid,
+ PVR_DESCRAMBLE_INFO* descrambleInfo)
+ {
+ PVRDescrambleInfo cppDescrambleInfo(descrambleInfo);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetDescrambleInfo(channelUid, cppDescrambleInfo);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ inline static PVR_ERROR ADDON_GetProvidersAmount(const AddonInstance_PVR* instance, int* amount)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetProvidersAmount(*amount);
+ }
+
+ inline static PVR_ERROR ADDON_GetProviders(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ {
+ PVRProvidersResultSet result(instance, handle);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->GetProviders(result);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ inline static PVR_ERROR ADDON_GetChannelGroupsAmount(const AddonInstance_PVR* instance,
+ int* amount)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetChannelGroupsAmount(*amount);
+ }
+
+ inline static PVR_ERROR ADDON_GetChannelGroups(const AddonInstance_PVR* instance,
+ PVR_HANDLE handle,
+ bool radio)
+ {
+ PVRChannelGroupsResultSet result(instance, handle);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetChannelGroups(radio, result);
+ }
+
+ inline static PVR_ERROR ADDON_GetChannelGroupMembers(const AddonInstance_PVR* instance,
+ PVR_HANDLE handle,
+ const PVR_CHANNEL_GROUP* group)
+ {
+ PVRChannelGroupMembersResultSet result(instance, handle);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetChannelGroupMembers(group, result);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ inline static PVR_ERROR ADDON_DeleteChannel(const AddonInstance_PVR* instance,
+ const PVR_CHANNEL* channel)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->DeleteChannel(channel);
+ }
+
+ inline static PVR_ERROR ADDON_RenameChannel(const AddonInstance_PVR* instance,
+ const PVR_CHANNEL* channel)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->RenameChannel(channel);
+ }
+
+ inline static PVR_ERROR ADDON_OpenDialogChannelSettings(const AddonInstance_PVR* instance,
+ const PVR_CHANNEL* channel)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->OpenDialogChannelSettings(channel);
+ }
+
+ inline static PVR_ERROR ADDON_OpenDialogChannelAdd(const AddonInstance_PVR* instance,
+ const PVR_CHANNEL* channel)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->OpenDialogChannelAdd(channel);
+ }
+
+ inline static PVR_ERROR ADDON_OpenDialogChannelScan(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->OpenDialogChannelScan();
+ }
+
+ inline static PVR_ERROR ADDON_CallChannelMenuHook(const AddonInstance_PVR* instance,
+ const PVR_MENUHOOK* menuhook,
+ const PVR_CHANNEL* channel)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->CallChannelMenuHook(menuhook, channel);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ inline static PVR_ERROR ADDON_GetEPGForChannel(const AddonInstance_PVR* instance,
+ PVR_HANDLE handle,
+ int channelUid,
+ time_t start,
+ time_t end)
+ {
+ PVREPGTagsResultSet result(instance, handle);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetEPGForChannel(channelUid, start, end, result);
+ }
+
+ inline static PVR_ERROR ADDON_IsEPGTagRecordable(const AddonInstance_PVR* instance,
+ const EPG_TAG* tag,
+ bool* isRecordable)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->IsEPGTagRecordable(tag, *isRecordable);
+ }
+
+ inline static PVR_ERROR ADDON_IsEPGTagPlayable(const AddonInstance_PVR* instance,
+ const EPG_TAG* tag,
+ bool* isPlayable)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->IsEPGTagPlayable(tag, *isPlayable);
+ }
+
+ inline static PVR_ERROR ADDON_GetEPGTagEdl(const AddonInstance_PVR* instance,
+ const EPG_TAG* tag,
+ PVR_EDL_ENTRY* edl,
+ int* size)
+ {
+ std::vector<PVREDLEntry> edlList;
+ PVR_ERROR error = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetEPGTagEdl(tag, edlList);
+ if (static_cast<int>(edlList.size()) > *size)
+ {
+ kodi::Log(
+ ADDON_LOG_WARNING,
+ "CInstancePVRClient::%s: Truncating %d EDL entries from client to permitted size %d",
+ __func__, static_cast<int>(edlList.size()), *size);
+ edlList.resize(*size);
+ }
+ *size = 0;
+ if (error == PVR_ERROR_NO_ERROR)
+ {
+ for (const auto& edlEntry : edlList)
+ {
+ edl[*size] = *edlEntry;
+ ++*size;
+ }
+ }
+ return error;
+ }
+
+ inline static PVR_ERROR ADDON_GetEPGTagStreamProperties(const AddonInstance_PVR* instance,
+ const EPG_TAG* tag,
+ PVR_NAMED_VALUE* properties,
+ unsigned int* propertiesCount)
+ {
+ *propertiesCount = 0;
+ std::vector<PVRStreamProperty> propertiesList;
+ PVR_ERROR error = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetEPGTagStreamProperties(tag, propertiesList);
+ if (error == PVR_ERROR_NO_ERROR)
+ {
+ for (const auto& property : propertiesList)
+ {
+ strncpy(properties[*propertiesCount].strName, property.GetCStructure()->strName,
+ sizeof(properties[*propertiesCount].strName) - 1);
+ strncpy(properties[*propertiesCount].strValue, property.GetCStructure()->strValue,
+ sizeof(properties[*propertiesCount].strValue) - 1);
+ ++*propertiesCount;
+ if (*propertiesCount > STREAM_MAX_PROPERTY_COUNT)
+ break;
+ }
+ }
+ return error;
+ }
+
+ inline static PVR_ERROR ADDON_SetEPGMaxPastDays(const AddonInstance_PVR* instance, int pastDays)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SetEPGMaxPastDays(pastDays);
+ }
+
+ inline static PVR_ERROR ADDON_SetEPGMaxFutureDays(const AddonInstance_PVR* instance,
+ int futureDays)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SetEPGMaxFutureDays(futureDays);
+ }
+
+ inline static PVR_ERROR ADDON_CallEPGMenuHook(const AddonInstance_PVR* instance,
+ const PVR_MENUHOOK* menuhook,
+ const EPG_TAG* tag)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->CallEPGMenuHook(menuhook, tag);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ inline static PVR_ERROR ADDON_GetRecordingsAmount(const AddonInstance_PVR* instance,
+ bool deleted,
+ int* amount)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetRecordingsAmount(deleted, *amount);
+ }
+
+ inline static PVR_ERROR ADDON_GetRecordings(const AddonInstance_PVR* instance,
+ PVR_HANDLE handle,
+ bool deleted)
+ {
+ PVRRecordingsResultSet result(instance, handle);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetRecordings(deleted, result);
+ }
+
+ inline static PVR_ERROR ADDON_DeleteRecording(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->DeleteRecording(recording);
+ }
+
+ inline static PVR_ERROR ADDON_UndeleteRecording(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->UndeleteRecording(recording);
+ }
+
+ inline static PVR_ERROR ADDON_DeleteAllRecordingsFromTrash(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->DeleteAllRecordingsFromTrash();
+ }
+
+ inline static PVR_ERROR ADDON_RenameRecording(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->RenameRecording(recording);
+ }
+
+ inline static PVR_ERROR ADDON_SetRecordingLifetime(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SetRecordingLifetime(recording);
+ }
+
+ inline static PVR_ERROR ADDON_SetRecordingPlayCount(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording,
+ int count)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SetRecordingPlayCount(recording, count);
+ }
+
+ inline static PVR_ERROR ADDON_SetRecordingLastPlayedPosition(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording,
+ int lastplayedposition)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SetRecordingLastPlayedPosition(recording, lastplayedposition);
+ }
+
+ inline static PVR_ERROR ADDON_GetRecordingLastPlayedPosition(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording,
+ int* position)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetRecordingLastPlayedPosition(recording, *position);
+ }
+
+ inline static PVR_ERROR ADDON_GetRecordingEdl(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording,
+ PVR_EDL_ENTRY* edl,
+ int* size)
+ {
+ std::vector<PVREDLEntry> edlList;
+ PVR_ERROR error = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetRecordingEdl(recording, edlList);
+ if (static_cast<int>(edlList.size()) > *size)
+ {
+ kodi::Log(
+ ADDON_LOG_WARNING,
+ "CInstancePVRClient::%s: Truncating %d EDL entries from client to permitted size %d",
+ __func__, static_cast<int>(edlList.size()), *size);
+ edlList.resize(*size);
+ }
+ *size = 0;
+ if (error == PVR_ERROR_NO_ERROR)
+ {
+ for (const auto& edlEntry : edlList)
+ {
+ edl[*size] = *edlEntry;
+ ++*size;
+ }
+ }
+ return error;
+ }
+
+ inline static PVR_ERROR ADDON_GetRecordingSize(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording,
+ int64_t* size)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetRecordingSize(recording, *size);
+ }
+
+ inline static PVR_ERROR ADDON_GetRecordingStreamProperties(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording,
+ PVR_NAMED_VALUE* properties,
+ unsigned int* propertiesCount)
+ {
+ *propertiesCount = 0;
+ std::vector<PVRStreamProperty> propertiesList;
+ PVR_ERROR error = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetRecordingStreamProperties(recording, propertiesList);
+ if (error == PVR_ERROR_NO_ERROR)
+ {
+ for (const auto& property : propertiesList)
+ {
+ strncpy(properties[*propertiesCount].strName, property.GetCStructure()->strName,
+ sizeof(properties[*propertiesCount].strName) - 1);
+ strncpy(properties[*propertiesCount].strValue, property.GetCStructure()->strValue,
+ sizeof(properties[*propertiesCount].strValue) - 1);
+ ++*propertiesCount;
+ if (*propertiesCount > STREAM_MAX_PROPERTY_COUNT)
+ break;
+ }
+ }
+ return error;
+ }
+
+ inline static PVR_ERROR ADDON_CallRecordingMenuHook(const AddonInstance_PVR* instance,
+ const PVR_MENUHOOK* menuhook,
+ const PVR_RECORDING* recording)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->CallRecordingMenuHook(menuhook, recording);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+
+ inline static PVR_ERROR ADDON_GetTimerTypes(const AddonInstance_PVR* instance,
+ PVR_TIMER_TYPE* types,
+ int* typesCount)
+ {
+ *typesCount = 0;
+ std::vector<PVRTimerType> timerTypes;
+ PVR_ERROR error = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetTimerTypes(timerTypes);
+ if (error == PVR_ERROR_NO_ERROR)
+ {
+ for (const auto& timerType : timerTypes)
+ {
+ types[*typesCount] = *timerType;
+ ++*typesCount;
+ if (*typesCount >= PVR_ADDON_TIMERTYPE_ARRAY_SIZE)
+ break;
+ }
+ }
+ return error;
+ }
+
+ inline static PVR_ERROR ADDON_GetTimersAmount(const AddonInstance_PVR* instance, int* amount)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetTimersAmount(*amount);
+ }
+
+ inline static PVR_ERROR ADDON_GetTimers(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ {
+ PVRTimersResultSet result(instance, handle);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->GetTimers(result);
+ }
+
+ inline static PVR_ERROR ADDON_AddTimer(const AddonInstance_PVR* instance, const PVR_TIMER* timer)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->AddTimer(timer);
+ }
+
+ inline static PVR_ERROR ADDON_DeleteTimer(const AddonInstance_PVR* instance,
+ const PVR_TIMER* timer,
+ bool forceDelete)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->DeleteTimer(timer, forceDelete);
+ }
+
+ inline static PVR_ERROR ADDON_UpdateTimer(const AddonInstance_PVR* instance,
+ const PVR_TIMER* timer)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->UpdateTimer(timer);
+ }
+
+ inline static PVR_ERROR ADDON_CallTimerMenuHook(const AddonInstance_PVR* instance,
+ const PVR_MENUHOOK* menuhook,
+ const PVR_TIMER* timer)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->CallTimerMenuHook(menuhook, timer);
+ }
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+
+ inline static PVR_ERROR ADDON_OnSystemSleep(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->OnSystemSleep();
+ }
+
+ inline static PVR_ERROR ADDON_OnSystemWake(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->OnSystemWake();
+ }
+
+ inline static PVR_ERROR ADDON_OnPowerSavingActivated(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->OnPowerSavingActivated();
+ }
+
+ inline static PVR_ERROR ADDON_OnPowerSavingDeactivated(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->OnPowerSavingDeactivated();
+ }
+
+ // obsolete parts below
+ ///@{
+
+ inline static bool ADDON_OpenLiveStream(const AddonInstance_PVR* instance,
+ const PVR_CHANNEL* channel)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->OpenLiveStream(channel);
+ }
+
+ inline static void ADDON_CloseLiveStream(const AddonInstance_PVR* instance)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->CloseLiveStream();
+ }
+
+ inline static int ADDON_ReadLiveStream(const AddonInstance_PVR* instance,
+ unsigned char* buffer,
+ unsigned int size)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->ReadLiveStream(buffer, size);
+ }
+
+ inline static int64_t ADDON_SeekLiveStream(const AddonInstance_PVR* instance,
+ int64_t position,
+ int whence)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SeekLiveStream(position, whence);
+ }
+
+ inline static int64_t ADDON_LengthLiveStream(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->LengthLiveStream();
+ }
+
+ inline static PVR_ERROR ADDON_GetStreamProperties(const AddonInstance_PVR* instance,
+ PVR_STREAM_PROPERTIES* properties)
+ {
+ properties->iStreamCount = 0;
+ std::vector<PVRStreamProperties> cppProperties;
+ PVR_ERROR err = static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetStreamProperties(cppProperties);
+ if (err == PVR_ERROR_NO_ERROR)
+ {
+ for (unsigned int i = 0; i < cppProperties.size(); ++i)
+ {
+ memcpy(&properties->stream[i],
+ static_cast<PVR_STREAM_PROPERTIES::PVR_STREAM*>(cppProperties[i]),
+ sizeof(PVR_STREAM_PROPERTIES::PVR_STREAM));
+ ++properties->iStreamCount;
+
+ if (properties->iStreamCount >= PVR_STREAM_MAX_STREAMS)
+ {
+ kodi::Log(
+ ADDON_LOG_ERROR,
+ "CInstancePVRClient::%s: Addon given with '%li' more allowed streams where '%i'",
+ __func__, cppProperties.size(), PVR_STREAM_MAX_STREAMS);
+ break;
+ }
+ }
+ }
+
+ return err;
+ }
+
+ inline static PVR_ERROR ADDON_GetStreamReadChunkSize(const AddonInstance_PVR* instance,
+ int* chunksize)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetStreamReadChunkSize(*chunksize);
+ }
+
+ inline static bool ADDON_IsRealTimeStream(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->IsRealTimeStream();
+ }
+
+ inline static bool ADDON_OpenRecordedStream(const AddonInstance_PVR* instance,
+ const PVR_RECORDING* recording)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->OpenRecordedStream(recording);
+ }
+
+ inline static void ADDON_CloseRecordedStream(const AddonInstance_PVR* instance)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->CloseRecordedStream();
+ }
+
+ inline static int ADDON_ReadRecordedStream(const AddonInstance_PVR* instance,
+ unsigned char* buffer,
+ unsigned int size)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->ReadRecordedStream(buffer, size);
+ }
+
+ inline static int64_t ADDON_SeekRecordedStream(const AddonInstance_PVR* instance,
+ int64_t position,
+ int whence)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SeekRecordedStream(position, whence);
+ }
+
+ inline static int64_t ADDON_LengthRecordedStream(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->LengthRecordedStream();
+ }
+
+ inline static void ADDON_DemuxReset(const AddonInstance_PVR* instance)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->DemuxReset();
+ }
+
+ inline static void ADDON_DemuxAbort(const AddonInstance_PVR* instance)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->DemuxAbort();
+ }
+
+ inline static void ADDON_DemuxFlush(const AddonInstance_PVR* instance)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->DemuxFlush();
+ }
+
+ inline static DEMUX_PACKET* ADDON_DemuxRead(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->DemuxRead();
+ }
+
+ inline static bool ADDON_CanPauseStream(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->CanPauseStream();
+ }
+
+ inline static bool ADDON_CanSeekStream(const AddonInstance_PVR* instance)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->CanSeekStream();
+ }
+
+ inline static void ADDON_PauseStream(const AddonInstance_PVR* instance, bool bPaused)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->PauseStream(bPaused);
+ }
+
+ inline static bool ADDON_SeekTime(const AddonInstance_PVR* instance,
+ double time,
+ bool backwards,
+ double* startpts)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SeekTime(time, backwards, *startpts);
+ }
+
+ inline static void ADDON_SetSpeed(const AddonInstance_PVR* instance, int speed)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->SetSpeed(speed);
+ }
+
+ inline static void ADDON_FillBuffer(const AddonInstance_PVR* instance, bool mode)
+ {
+ static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)->FillBuffer(mode);
+ }
+
+ inline static PVR_ERROR ADDON_GetStreamTimes(const AddonInstance_PVR* instance,
+ PVR_STREAM_TIMES* times)
+ {
+ PVRStreamTimes cppTimes(times);
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->GetStreamTimes(cppTimes);
+ }
+ ///@}
+
+ AddonInstance_PVR* m_instanceData = nullptr;
+};
+//}}}
+//______________________________________________________________________________
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h
new file mode 100644
index 0000000..ea07498
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h
@@ -0,0 +1,889 @@
+/*
+ * Copyright (C) 2014-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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "peripheral/PeripheralUtils.h"
+
+#ifdef __cplusplus
+namespace kodi
+{
+namespace addon
+{
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_peripheral_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_peripheral
+/// @brief %Peripheral add-on general variables
+///
+/// Used to exchange the available options between Kodi and addon.
+///
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_peripheral_Defs_General 1. General
+/// @ingroup cpp_kodi_addon_peripheral_Defs
+/// @brief **%Peripheral add-on general variables**\n
+/// Used to exchange the available options between Kodi and addon.
+///
+/// This group also includes @ref cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities
+/// with which Kodi an @ref kodi::addon::CInstancePeripheral::GetCapabilities()
+/// queries the supported **modules** of the addon.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Peripheral 2. Peripheral
+/// @ingroup cpp_kodi_addon_peripheral_Defs
+/// @brief **%Peripheral add-on operation variables**\n
+/// Used to exchange the available options between Kodi and addon.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Event 3. Event
+/// @ingroup cpp_kodi_addon_peripheral_Defs
+/// @brief **%Event add-on operation variables**\n
+/// Used to exchange the available options between Kodi and addon.
+///
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick 4. Joystick
+/// @ingroup cpp_kodi_addon_peripheral_Defs
+/// @brief **%Joystick add-on operation variables**\n
+/// Used to exchange the available options between Kodi and addon.
+///
+
+//==============================================================================
+/// @addtogroup cpp_kodi_addon_peripheral
+/// @brief \cpp_class{ kodi::addon::CInstancePeripheral }
+/// **%Peripheral add-on instance**
+///
+/// The peripheral add-ons provides access to many joystick and gamepad
+/// interfaces across various platforms. An input addon is used to map the
+/// buttons/axis on your physical input device, to the buttons/axis of your
+/// virtual system. This is necessary because different retro systems usually
+/// have different button layouts. A controller configuration utility is also
+/// in the works.
+///
+/// ----------------------------------------------------------------------------
+///
+/// Here is an example of what the <b>`addon.xml.in`</b> would look like for an
+/// peripheral addon:
+///
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="peripheral.myspecialnamefor"
+/// version="1.0.0"
+/// name="My special peripheral addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="kodi.peripheral"
+/// provides_joysticks="true"
+/// provides_buttonmaps="true"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My peripheral addon</summary>
+/// <description lang="en_GB">My peripheral addon description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+/// Description to peripheral related addon.xml values:
+/// | Name | Description
+/// |:------------------------------|----------------------------------------
+/// | <b>`provides_joysticks`</b> | Set to "true" if addon provides joystick support.
+/// | <b>`provides_buttonmaps`</b> | Set to "true" if button map is used and supported by addon.
+/// | <b>`point`</b> | Addon type specification<br>At all addon types and for this kind always <b>"kodi.peripheral"</b>.
+/// | <b>`library_@PLATFORM@`</b> | Sets the used library name, which is automatically set by cmake at addon build.
+///
+/// @remark For more detailed description of the <b>`addon.xml`</b>, see also https://kodi.wiki/view/Addon.xml.
+///
+///
+/// --------------------------------------------------------------------------
+///
+/// **Here is an example of how addon can be used as a single:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/Peripheral.h>
+///
+/// class CMyPeripheralAddon : public kodi::addon::CAddonBase,
+/// public kodi::addon::CInstancePeripheral
+/// {
+/// public:
+/// CMyPeripheralAddon();
+///
+/// void GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities) override;
+/// ...
+/// };
+///
+/// CMyPeripheralAddon::CMyPeripheralAddon()
+/// {
+/// ...
+/// }
+///
+/// void CMyPeripheralAddon::GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities)
+/// {
+/// capabilities.SetProvidesJoysticks(true);
+/// capabilities.SetProvidesButtonmaps(true);
+/// ...
+/// }
+///
+/// ADDONCREATOR(CMyPeripheralAddon)
+/// ~~~~~~~~~~~~~
+///
+/// @note It is imperative to use the necessary functions of this class in the
+/// addon.
+///
+/// --------------------------------------------------------------------------
+///
+///
+/// **Here is another example where the peripheral is used together with
+/// other instance types:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/Peripheral.h>
+///
+/// class CMyPeripheralAddon : public kodi::addon::CInstancePeripheral
+/// {
+/// public:
+/// CMyPeripheralAddon(const kodi::addon::IInstanceInfo& instance);
+///
+/// void GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities) override;
+/// ...
+/// };
+///
+/// CMyPeripheralAddon::CMyPeripheralAddon(const kodi::addon::IInstanceInfo& instance)
+/// : CInstancePeripheral(instance)
+/// {
+/// ...
+/// }
+///
+/// void CMyPeripheralAddon::GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities)
+/// {
+/// capabilities.SetProvidesJoysticks(true);
+/// capabilities.SetProvidesButtonmaps(true);
+/// ...
+/// }
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_PERIPHERAL))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my peripheral addon");
+/// addonInstance = new CMyPeripheralAddon(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyPeripheralAddon` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+class ATTR_DLL_LOCAL CInstancePeripheral : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_peripheral
+ /// @brief Peripheral class constructor.
+ ///
+ /// Used by an add-on that only supports peripheral.
+ ///
+ CInstancePeripheral()
+ : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstancePeripheral: Creation of more as one in single "
+ "instance way is not allowed!");
+
+ SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
+ CPrivateBase::m_interface->globalSingleInstance = this;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_peripheral
+ /// @brief Peripheral addon class constructor used to support multiple
+ /// instance types.
+ ///
+ /// @param[in] instance The instance value given to
+ /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ //////*Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// class CMyPeripheralAddon : public kodi::addon::CInstancePeripheral
+ /// {
+ /// public:
+ /// CMyPeripheralAddon(const kodi::addon::IInstanceInfo& instance)
+ /// : kodi::addon::CInstancePeripheral(instance)
+ /// {
+ /// ...
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ /// KODI_ADDON_INSTANCE_HDL& hdl)
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my peripheral");
+ /// hdl = new CMyPeripheralAddon(instance,);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ explicit CInstancePeripheral(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstancePeripheral: Creation of multiple together with "
+ "single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_peripheral
+ /// @brief Destructor.
+ ///
+ ~CInstancePeripheral() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_peripheralOp 1. Peripheral operations
+ /// @ingroup cpp_kodi_addon_peripheral
+ /// @brief %Peripheral operations to handle control about.
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **%Peripheral parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_peripheral_peripheralOp_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_peripheral_peripheralOp_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Get the list of features that this add-on provides.
+ ///
+ /// Called by the frontend to query the add-on's capabilities and supported
+ /// peripherals. All capabilities that the add-on supports should be set to true.
+ ///
+ /// @param[out] capabilities The add-on's capabilities
+ ///
+ /// @remarks Valid implementation required.
+ ///
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities_Help
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// void CMyPeripheralAddon::GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities)
+ /// {
+ /// capabilities.SetProvidesJoysticks(true);
+ /// capabilities.SetProvidesButtonmaps(true);
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual void GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Perform a scan for joysticks
+ ///
+ /// The frontend calls this when a hardware change is detected. If an add-on
+ /// detects a hardware change, it can trigger this function using the
+ /// @ref TriggerScan() callback.
+ ///
+ /// @param[in] scan_results Assigned to allocated memory
+ /// @return @ref PERIPHERAL_NO_ERROR if successful
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral_Help
+ ///
+ virtual PERIPHERAL_ERROR PerformDeviceScan(
+ std::vector<std::shared_ptr<kodi::addon::Peripheral>>& scan_results)
+ {
+ return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get all events that have occurred since the last call to
+ /// @ref GetEvents().
+ ///
+ /// @param[out] events List of available events within addon
+ /// @return @ref PERIPHERAL_NO_ERROR if successful
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent_Help
+ ///
+ virtual PERIPHERAL_ERROR GetEvents(std::vector<kodi::addon::PeripheralEvent>& events)
+ {
+ return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Send an input event to the peripheral.
+ ///
+ /// @param[in] event The input event
+ /// @return true if the event was handled, false otherwise
+ ///
+ virtual bool SendEvent(const kodi::addon::PeripheralEvent& event) { return false; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_joystickOp 2. Joystick operations
+ /// @ingroup cpp_kodi_addon_peripheral
+ /// @brief %Joystick operations to handle control about.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **%Joystick parts in interface:**\n
+ /// Copy this to your project and extend with your parts or leave functions
+ /// complete away where not used or supported.
+ ///
+ /// @copydetails cpp_kodi_addon_peripheral_joystickOp_header_addon_auto_check
+ /// @copydetails cpp_kodi_addon_peripheral_joystickOp_source_addon_auto_check
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Get extended info about an attached joystick.
+ ///
+ /// @param[in] index The joystick's driver index
+ /// @param[out] info The container for the allocated joystick info
+ /// @return @ref PERIPHERAL_NO_ERROR if successful
+ ///
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_peripheral_Defs_Joystick_Joystick_Help
+ ///
+ virtual PERIPHERAL_ERROR GetJoystickInfo(unsigned int index, kodi::addon::Joystick& info)
+ {
+ return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the features that allow translating the joystick into the
+ /// controller profile.
+ ///
+ /// @param[in] joystick The device's joystick properties; unknown values may
+ /// be left at their default
+ /// @param[in] controller_id The controller profile being requested, e.g.
+ /// `game.controller.default`
+ /// @param[out] features The array of allocated features
+ /// @return @ref PERIPHERAL_NO_ERROR if successful
+ ///
+ virtual PERIPHERAL_ERROR GetFeatures(const kodi::addon::Joystick& joystick,
+ const std::string& controller_id,
+ std::vector<kodi::addon::JoystickFeature>& features)
+ {
+ return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Add or update joystick features.
+ ///
+ /// @param[in] joystick The device's joystick properties; unknown values may be
+ /// left at their default
+ /// @param[in] controller_id The game controller profile being updated
+ /// @param[in] features The array of features
+ /// @return @ref PERIPHERAL_NO_ERROR if successful
+ ///
+ virtual PERIPHERAL_ERROR MapFeatures(const kodi::addon::Joystick& joystick,
+ const std::string& controller_id,
+ const std::vector<kodi::addon::JoystickFeature>& features)
+ {
+ return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get the driver primitives that should be ignored while mapping the
+ /// device.
+ ///
+ /// @param[in] joystick The device's joystick properties; unknown values may
+ /// be left at their default
+ /// @param[out] primitives The array of allocated driver primitives to be
+ /// ignored
+ /// @return @ref PERIPHERAL_NO_ERROR if successful
+ ///
+ virtual PERIPHERAL_ERROR GetIgnoredPrimitives(
+ const kodi::addon::Joystick& joystick, std::vector<kodi::addon::DriverPrimitive>& primitives)
+ {
+ return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Set the list of driver primitives that are ignored for the device.
+ ///
+ /// @param[in] joystick The device's joystick properties; unknown values may be left at their default
+ /// @param[in] primitives The array of driver primitives to ignore
+ /// @return @ref PERIPHERAL_NO_ERROR if successful
+ ///
+ virtual PERIPHERAL_ERROR SetIgnoredPrimitives(
+ const kodi::addon::Joystick& joystick,
+ const std::vector<kodi::addon::DriverPrimitive>& primitives)
+ {
+ return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Save the button map for the given joystick.
+ ///
+ /// @param[in] joystick The device's joystick properties
+ ///
+ virtual void SaveButtonMap(const kodi::addon::Joystick& joystick) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Revert the button map to the last time it was loaded or committed to disk
+ /// @param[in] joystick The device's joystick properties
+ ///
+ virtual void RevertButtonMap(const kodi::addon::Joystick& joystick) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Reset the button map for the given joystick and controller profile ID
+ /// @param[in] joystick The device's joystick properties
+ /// @param[in] controller_id The game controller profile being reset
+ ///
+ virtual void ResetButtonMap(const kodi::addon::Joystick& joystick,
+ const std::string& controller_id)
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Powers off the given joystick if supported
+ /// @param[in] index The joystick's driver index
+ ///
+ virtual void PowerOffJoystick(unsigned int index) {}
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_callbacks 3. Callback functions
+ /// @ingroup cpp_kodi_addon_peripheral
+ /// @brief Callback to Kodi functions.
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Used to get the full path where the add-on is installed.
+ ///
+ /// @return The add-on installation path
+ ///
+ const std::string AddonPath() const { return m_instanceData->props->addon_path; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @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
+ ///
+ const std::string UserPath() const { return m_instanceData->props->user_path; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Trigger a scan for peripherals
+ ///
+ /// The add-on calls this if a change in hardware is detected.
+ ///
+ void TriggerScan(void)
+ {
+ return m_instanceData->toKodi->trigger_scan(m_instanceData->toKodi->kodiInstance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Notify the frontend that button maps have changed.
+ ///
+ /// @param[in] deviceName [optional] The name of the device to refresh, or
+ /// empty/null for all devices
+ /// @param[in] controllerId [optional] The controller ID to refresh, or
+ /// empty/null for all controllers
+ ///
+ void RefreshButtonMaps(const std::string& deviceName = "", const std::string& controllerId = "")
+ {
+ return m_instanceData->toKodi->refresh_button_maps(m_instanceData->toKodi->kodiInstance,
+ deviceName.c_str(), controllerId.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Return the number of features belonging to the specified
+ /// controller.
+ ///
+ /// @param[in] controllerId The controller ID to enumerate
+ /// @param[in] type [optional] Type to filter by, or @ref JOYSTICK_FEATURE_TYPE_UNKNOWN
+ /// for all features
+ /// @return The number of features matching the request parameters
+ ///
+ unsigned int FeatureCount(const std::string& controllerId,
+ JOYSTICK_FEATURE_TYPE type = JOYSTICK_FEATURE_TYPE_UNKNOWN)
+ {
+ return m_instanceData->toKodi->feature_count(m_instanceData->toKodi->kodiInstance,
+ controllerId.c_str(), type);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Return the type of the feature.
+ ///
+ /// @param[in] controllerId The controller ID to check
+ /// @param[in] featureName The feature to check
+ /// @return The type of the specified feature, or @ref JOYSTICK_FEATURE_TYPE_UNKNOWN
+ /// if unknown
+ ///
+ JOYSTICK_FEATURE_TYPE FeatureType(const std::string& controllerId, const std::string& featureName)
+ {
+ return m_instanceData->toKodi->feature_type(m_instanceData->toKodi->kodiInstance,
+ controllerId.c_str(), featureName.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+
+ instance->peripheral->toAddon->get_capabilities = ADDON_GetCapabilities;
+ instance->peripheral->toAddon->perform_device_scan = ADDON_PerformDeviceScan;
+ instance->peripheral->toAddon->free_scan_results = ADDON_FreeScanResults;
+ instance->peripheral->toAddon->get_events = ADDON_GetEvents;
+ instance->peripheral->toAddon->free_events = ADDON_FreeEvents;
+ instance->peripheral->toAddon->send_event = ADDON_SendEvent;
+
+ instance->peripheral->toAddon->get_joystick_info = ADDON_GetJoystickInfo;
+ instance->peripheral->toAddon->free_joystick_info = ADDON_FreeJoystickInfo;
+ instance->peripheral->toAddon->get_features = ADDON_GetFeatures;
+ instance->peripheral->toAddon->free_features = ADDON_FreeFeatures;
+ instance->peripheral->toAddon->map_features = ADDON_MapFeatures;
+ instance->peripheral->toAddon->get_ignored_primitives = ADDON_GetIgnoredPrimitives;
+ instance->peripheral->toAddon->free_primitives = ADDON_FreePrimitives;
+ instance->peripheral->toAddon->set_ignored_primitives = ADDON_SetIgnoredPrimitives;
+ instance->peripheral->toAddon->save_button_map = ADDON_SaveButtonMap;
+ instance->peripheral->toAddon->revert_button_map = ADDON_RevertButtonMap;
+ instance->peripheral->toAddon->reset_button_map = ADDON_ResetButtonMap;
+ instance->peripheral->toAddon->power_off_joystick = ADDON_PowerOffJoystick;
+
+ m_instanceData = instance->peripheral;
+ m_instanceData->toAddon->addonInstance = this;
+ }
+
+ inline static void ADDON_GetCapabilities(const AddonInstance_Peripheral* addonInstance,
+ PERIPHERAL_CAPABILITIES* capabilities)
+ {
+ if (!addonInstance || !capabilities)
+ return;
+
+ kodi::addon::PeripheralCapabilities peripheralCapabilities(capabilities);
+ static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetCapabilities(peripheralCapabilities);
+ }
+
+ inline static PERIPHERAL_ERROR ADDON_PerformDeviceScan(
+ const AddonInstance_Peripheral* addonInstance,
+ unsigned int* peripheral_count,
+ PERIPHERAL_INFO** scan_results)
+ {
+ if (!addonInstance || !peripheral_count || !scan_results)
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
+
+ std::vector<std::shared_ptr<kodi::addon::Peripheral>> peripherals;
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->PerformDeviceScan(peripherals);
+ if (err == PERIPHERAL_NO_ERROR)
+ {
+ *peripheral_count = static_cast<unsigned int>(peripherals.size());
+ kodi::addon::Peripherals::ToStructs(peripherals, scan_results);
+ }
+
+ return err;
+ }
+
+ inline static void ADDON_FreeScanResults(const AddonInstance_Peripheral* addonInstance,
+ unsigned int peripheral_count,
+ PERIPHERAL_INFO* scan_results)
+ {
+ if (!addonInstance)
+ return;
+
+ kodi::addon::Peripherals::FreeStructs(peripheral_count, scan_results);
+ }
+
+ inline static PERIPHERAL_ERROR ADDON_GetEvents(const AddonInstance_Peripheral* addonInstance,
+ unsigned int* event_count,
+ PERIPHERAL_EVENT** events)
+ {
+ if (!addonInstance || !event_count || !events)
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
+
+ std::vector<kodi::addon::PeripheralEvent> peripheralEvents;
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetEvents(peripheralEvents);
+ if (err == PERIPHERAL_NO_ERROR)
+ {
+ *event_count = static_cast<unsigned int>(peripheralEvents.size());
+ kodi::addon::PeripheralEvents::ToStructs(peripheralEvents, events);
+ }
+
+ return err;
+ }
+
+ inline static void ADDON_FreeEvents(const AddonInstance_Peripheral* addonInstance,
+ unsigned int event_count,
+ PERIPHERAL_EVENT* events)
+ {
+ if (!addonInstance)
+ return;
+
+ kodi::addon::PeripheralEvents::FreeStructs(event_count, events);
+ }
+
+ inline static bool ADDON_SendEvent(const AddonInstance_Peripheral* addonInstance,
+ const PERIPHERAL_EVENT* event)
+ {
+ if (!addonInstance || !event)
+ return false;
+ return static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->SendEvent(kodi::addon::PeripheralEvent(*event));
+ }
+
+
+ inline static PERIPHERAL_ERROR ADDON_GetJoystickInfo(
+ const AddonInstance_Peripheral* addonInstance, unsigned int index, JOYSTICK_INFO* info)
+ {
+ if (!addonInstance || !info)
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
+
+ kodi::addon::Joystick addonInfo;
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetJoystickInfo(index, addonInfo);
+ if (err == PERIPHERAL_NO_ERROR)
+ {
+ addonInfo.ToStruct(*info);
+ }
+
+ return err;
+ }
+
+ inline static void ADDON_FreeJoystickInfo(const AddonInstance_Peripheral* addonInstance,
+ JOYSTICK_INFO* info)
+ {
+ if (!addonInstance)
+ return;
+
+ kodi::addon::Joystick::FreeStruct(*info);
+ }
+
+ inline static PERIPHERAL_ERROR ADDON_GetFeatures(const AddonInstance_Peripheral* addonInstance,
+ const JOYSTICK_INFO* joystick,
+ const char* controller_id,
+ unsigned int* feature_count,
+ JOYSTICK_FEATURE** features)
+ {
+ if (!addonInstance || !joystick || !controller_id || !feature_count || !features)
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
+
+ kodi::addon::Joystick addonJoystick(*joystick);
+ std::vector<kodi::addon::JoystickFeature> featuresVector;
+
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetFeatures(addonJoystick, controller_id, featuresVector);
+ if (err == PERIPHERAL_NO_ERROR)
+ {
+ *feature_count = static_cast<unsigned int>(featuresVector.size());
+ kodi::addon::JoystickFeatures::ToStructs(featuresVector, features);
+ }
+
+ return err;
+ }
+
+ inline static void ADDON_FreeFeatures(const AddonInstance_Peripheral* addonInstance,
+ unsigned int feature_count,
+ JOYSTICK_FEATURE* features)
+ {
+ if (!addonInstance)
+ return;
+
+ kodi::addon::JoystickFeatures::FreeStructs(feature_count, features);
+ }
+
+ inline static PERIPHERAL_ERROR ADDON_MapFeatures(const AddonInstance_Peripheral* addonInstance,
+ const JOYSTICK_INFO* joystick,
+ const char* controller_id,
+ unsigned int feature_count,
+ const JOYSTICK_FEATURE* features)
+ {
+ if (!addonInstance || !joystick || !controller_id || (feature_count > 0 && !features))
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
+
+ kodi::addon::Joystick addonJoystick(*joystick);
+ std::vector<kodi::addon::JoystickFeature> primitiveVector;
+
+ for (unsigned int i = 0; i < feature_count; i++)
+ primitiveVector.emplace_back(*(features + i));
+
+ return static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->MapFeatures(addonJoystick, controller_id, primitiveVector);
+ }
+
+ inline static PERIPHERAL_ERROR ADDON_GetIgnoredPrimitives(
+ const AddonInstance_Peripheral* addonInstance,
+ const JOYSTICK_INFO* joystick,
+ unsigned int* primitive_count,
+ JOYSTICK_DRIVER_PRIMITIVE** primitives)
+ {
+ if (!addonInstance || !joystick || !primitive_count || !primitives)
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
+
+ kodi::addon::Joystick addonJoystick(*joystick);
+ std::vector<kodi::addon::DriverPrimitive> primitiveVector;
+
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetIgnoredPrimitives(addonJoystick, primitiveVector);
+ if (err == PERIPHERAL_NO_ERROR)
+ {
+ *primitive_count = static_cast<unsigned int>(primitiveVector.size());
+ kodi::addon::DriverPrimitives::ToStructs(primitiveVector, primitives);
+ }
+
+ return err;
+ }
+
+ inline static void ADDON_FreePrimitives(const AddonInstance_Peripheral* addonInstance,
+ unsigned int primitive_count,
+ JOYSTICK_DRIVER_PRIMITIVE* primitives)
+ {
+ if (!addonInstance)
+ return;
+
+ kodi::addon::DriverPrimitives::FreeStructs(primitive_count, primitives);
+ }
+
+ inline static PERIPHERAL_ERROR ADDON_SetIgnoredPrimitives(
+ const AddonInstance_Peripheral* addonInstance,
+ const JOYSTICK_INFO* joystick,
+ unsigned int primitive_count,
+ const JOYSTICK_DRIVER_PRIMITIVE* primitives)
+ {
+ if (!addonInstance || !joystick || (primitive_count > 0 && !primitives))
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
+
+ kodi::addon::Joystick addonJoystick(*joystick);
+ std::vector<kodi::addon::DriverPrimitive> primitiveVector;
+
+ for (unsigned int i = 0; i < primitive_count; i++)
+ primitiveVector.emplace_back(*(primitives + i));
+
+ return static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->SetIgnoredPrimitives(addonJoystick, primitiveVector);
+ }
+
+ inline static void ADDON_SaveButtonMap(const AddonInstance_Peripheral* addonInstance,
+ const JOYSTICK_INFO* joystick)
+ {
+ if (!addonInstance || !joystick)
+ return;
+
+ kodi::addon::Joystick addonJoystick(*joystick);
+ static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->SaveButtonMap(addonJoystick);
+ }
+
+ inline static void ADDON_RevertButtonMap(const AddonInstance_Peripheral* addonInstance,
+ const JOYSTICK_INFO* joystick)
+ {
+ if (!addonInstance || !joystick)
+ return;
+
+ kodi::addon::Joystick addonJoystick(*joystick);
+ static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->RevertButtonMap(addonJoystick);
+ }
+
+ inline static void ADDON_ResetButtonMap(const AddonInstance_Peripheral* addonInstance,
+ const JOYSTICK_INFO* joystick,
+ const char* controller_id)
+ {
+ if (!addonInstance || !joystick || !controller_id)
+ return;
+
+ kodi::addon::Joystick addonJoystick(*joystick);
+ static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->ResetButtonMap(addonJoystick, controller_id);
+ }
+
+ inline static void ADDON_PowerOffJoystick(const AddonInstance_Peripheral* addonInstance,
+ unsigned int index)
+ {
+ if (!addonInstance)
+ return;
+
+ static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->PowerOffJoystick(index);
+ }
+
+ AddonInstance_Peripheral* m_instanceData;
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Screensaver.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Screensaver.h
new file mode 100644
index 0000000..1fd36fb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Screensaver.h
@@ -0,0 +1,424 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/addon-instance/screensaver.h"
+#include "../gui/renderHelper.h"
+
+#ifdef __cplusplus
+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 <kodi/addon-instance/ScreenSaver.h>"
+/// 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:
+///
+/// * <b><c>Start()</c></b> - Called on creation
+/// * <b><c>Render()</c></b> - Called at render time
+/// * <b><c>Stop()</c></b> - 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 what the <b>`addon.xml.in`</b> would look like for an
+/// screensaver addon:
+///
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="screensaver.myspecialnamefor"
+/// version="1.0.0"
+/// name="My special screensaver addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="xbmc.ui.screensaver"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My screensaver addon</summary>
+/// <description lang="en_GB">My screensaver addon description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+/// Description to screensaver related addon.xml values:
+/// | Name | Description
+/// |:------------------------------|----------------------------------------
+/// | <b>`point`</b> | Addon type specification<br>At all addon types and for this kind always <b>"xbmc.ui.screensaver"</b>.
+/// | <b>`library_@PLATFORM@`</b> | Sets the used library name, which is automatically set by cmake at addon build.
+///
+/// @remark For more detailed description of the <b>`addon.xml`</b>, see also https://kodi.wiki/view/Addon.xml.
+///
+///
+/// --------------------------------------------------------------------------
+///
+/// **Here is an example of the minimum required code to start a screensaver:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/Screensaver.h>
+///
+/// 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 <kodi/addon-instance/Screensaver.h>
+///
+/// class CMyScreenSaver : public kodi::addon::CInstanceScreensaver
+/// {
+/// public:
+/// CMyScreenSaver(const kodi::addon::IInstanceInfo& instance);
+///
+/// bool Start() override;
+/// void Render() override;
+/// };
+///
+/// CMyScreenSaver::CMyScreenSaver(const kodi::addon::IInstanceInfo& instance)
+/// : CInstanceScreensaver(instance)
+/// {
+/// ...
+/// }
+///
+/// bool CMyScreenSaver::Start()
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// void CMyScreenSaver::Render()
+/// {
+/// ...
+/// }
+///
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_SCREENSAVER))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my Screensaver");
+/// hdl = new CMyScreenSaver(instance, version);
+/// 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 ATTR_DLL_LOCAL CInstanceScreensaver : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_screensaver
+ /// @brief Screensaver class constructor.
+ ///
+ /// Used by an add-on that only supports screensavers.
+ ///
+ CInstanceScreensaver()
+ : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceScreensaver: Creation of more as one in single "
+ "instance way is not allowed!");
+
+ SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
+ CPrivateBase::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
+ /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>.
+ /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to
+ /// allow compatibility to older Kodi versions.
+ ///
+ /// @note Recommended to set <b>`kodiVersion`</b>.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// class CMyScreenSaver : public kodi::addon::CInstanceScreensaver
+ /// {
+ /// public:
+ /// CMyScreenSaver(KODI_HANDLE instance, const std::string& kodiVersion)
+ /// : kodi::addon::CInstanceScreensaver(instance, kodiVersion)
+ /// {
+ /// ...
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDON_STATUS CMyAddon::CreateInstance(int instanceType,
+ /// const std::string& instanceID,
+ /// KODI_HANDLE instance,
+ /// const std::string& version,
+ /// KODI_HANDLE& addonInstance)
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my screensaver");
+ /// addonInstance = new CMyScreenSaver(instance, version);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ explicit CInstanceScreensaver(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::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**
+ ///
+ /// This value can also be becomed by @ref kodi::gui::GetHWContext() and is
+ /// recommended to use.
+ ///
+ ///-------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <d3d11_1.h>
+ /// ..
+ /// // Note: Device() there is used inside addon child class about
+ /// // kodi::addon::CInstanceVisualization
+ /// ID3D11DeviceContext1* context = static_cast<ID3D11DeviceContext1*>(kodi::addon::CInstanceVisualization::Device());
+ /// ..
+ /// ~~~~~~~~~~~~~
+ ///
+ inline kodi::HardwareContext Device() { return m_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_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_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_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_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_props.pixelRatio; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+ instance->screensaver->toAddon->start = ADDON_start;
+ instance->screensaver->toAddon->stop = ADDON_stop;
+ instance->screensaver->toAddon->render = ADDON_render;
+
+ instance->screensaver->toKodi->get_properties(instance->info->kodi, &m_props);
+ }
+
+ inline static bool ADDON_start(const KODI_ADDON_SCREENSAVER_HDL hdl)
+ {
+ CInstanceScreensaver* thisClass = static_cast<CInstanceScreensaver*>(hdl);
+ thisClass->m_renderHelper = kodi::gui::GetRenderHelper();
+ return thisClass->Start();
+ }
+
+ inline static void ADDON_stop(const KODI_ADDON_SCREENSAVER_HDL hdl)
+ {
+ CInstanceScreensaver* thisClass = static_cast<CInstanceScreensaver*>(hdl);
+ thisClass->Stop();
+ thisClass->m_renderHelper = nullptr;
+ }
+
+ inline static void ADDON_render(const KODI_ADDON_SCREENSAVER_HDL hdl)
+ {
+ CInstanceScreensaver* thisClass = static_cast<CInstanceScreensaver*>(hdl);
+
+ if (!thisClass->m_renderHelper)
+ return;
+ thisClass->m_renderHelper->Begin();
+ thisClass->Render();
+ thisClass->m_renderHelper->End();
+ }
+
+ /*
+ * Background render helper holds here and in addon base.
+ * In addon base also to have for the others, and stored here for the worst
+ * case where this class is independent from base and base becomes closed
+ * before.
+ *
+ * This is on Kodi with GL unused and the calls to there are empty (no work)
+ * On Kodi with Direct X where angle is present becomes this used.
+ */
+ std::shared_ptr<kodi::gui::IRenderHelper> m_renderHelper;
+
+ KODI_ADDON_SCREENSAVER_PROPS m_props = {};
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h
new file mode 100644
index 0000000..6affffe
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h
@@ -0,0 +1,1211 @@
+/*
+ * Copyright (C) 2015-2018 Team Kodi
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../Filesystem.h"
+#include "../c-api/addon-instance/vfs.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+class CInstanceVFS;
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon_vfs_Defs
+/// @brief **VFS add-on file handle**\n
+/// This used to handle opened files of addon with related memory pointer about
+/// class or structure and to have on further file control functions available.
+///
+/// See @ref cpp_kodi_addon_vfs_filecontrol "file editing functions" for used
+/// places.
+///
+///@{
+using VFSFileHandle = VFS_FILE_HANDLE;
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_vfs_Defs_VFSUrl class VFSUrl
+/// @ingroup cpp_kodi_addon_vfs_Defs
+/// @brief **VFS add-on URL data**\n
+/// This class is used to inform the addon of the desired wanted connection.
+///
+/// Used on mostly all addon functions to identify related target.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_vfs_Defs_VFSUrl_Help
+///
+///@{
+class ATTR_DLL_LOCAL VFSUrl : public CStructHdl<VFSUrl, VFSURL>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceVFS;
+ /*! \endcond */
+
+public:
+ /// @defgroup cpp_kodi_addon_vfs_Defs_VFSUrl_Help Value Help
+ /// @ingroup cpp_kodi_addon_vfs_Defs_VFSUrl
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_vfs_Defs_VFSUrl :</b>
+ /// | Name | Type | Get call
+ /// |------|------|----------
+ /// | **URL** | `std::string` | @ref VFSUrl::GetURL "GetURL"
+ /// | **Domain name** | `std::string` | @ref VFSUrl::GetDomain "GetDomain"
+ /// | **Hostname** | `std::string` | @ref VFSUrl::GetHostname "GetHostname"
+ /// | **Filename** | `std::string` | @ref VFSUrl::GetFilename "GetFilename"
+ /// | **Network port** | `unsigned int` | @ref VFSUrl::GetPort "GetPort"
+ /// | **Special options** | `std::string` | @ref VFSUrl::GetOptions "GetOptions"
+ /// | **Username** | `std::string` | @ref VFSUrl::GetUsername "GetUsername"
+ /// | **Password** | `std::string` | @ref VFSUrl::GetPassword "GetPassword"
+ /// | **Get URL with user and password hidden** | `std::string` | @ref VFSUrl::GetRedacted "GetRedacted"
+ /// | **Sharename** | `std::string` | @ref VFSUrl::GetSharename "GetSharename"
+ /// | **Network protocol** | `std::string` | @ref VFSUrl::GetProtocol "GetProtocol"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_vfs_Defs_VFSUrl
+ ///@{
+
+ /// @brief Desired URL of the file system to be edited
+ ///
+ /// This includes all available parts of the access and is structured as
+ /// follows:
+ /// -
+ /// <b>`<PROTOCOL>`://`<USERNAME>`:`<PASSWORD>``@``<HOSTNAME>`:`<PORT>`/`<FILENAME>`?`<OPTIONS>`</b>
+ std::string GetURL() const { return m_cStructure->url; }
+
+ /// @brief The associated domain name, which is optional and not available
+ /// in all cases.
+ std::string GetDomain() const { return m_cStructure->domain; }
+
+ /// @brief This includes the network address (e.g. `192.168.0.123`) or if
+ /// the addon refers to file packages the path to it
+ /// (e.g. `/home/by_me/MyPacket.rar`).
+ std::string GetHostname() const { return m_cStructure->hostname; }
+
+ /// @brief With this variable the desired path to a folder or file within
+ /// the hostname is given (e.g. `storage/videos/00001.ts`).
+ std::string GetFilename() const { return m_cStructure->filename; }
+
+ /// @brief [Networking port](https://en.wikipedia.org/wiki/Port_(computer_networking))
+ /// to use for protocol.
+ unsigned int GetPort() const { return m_cStructure->port; }
+
+ /// @brief Special options on opened URL, this can e.g. on RAR packages
+ /// <b>`?flags=8&nextvalue=123`</b> to inform about to not cache a read.
+ ///
+ /// Available options from Kodi:
+ /// | Value: | Description:
+ /// |-----------|-------------------
+ /// | flags=8 | Used on RAR packages so that no data is cached from the requested source.
+ /// | cache=no | Used on ZIP packages so that no data from the requested source is stored in the cache. However, this is currently not available from addons!
+ ///
+ /// In addition, other addons can use the URLs given by them to give options
+ /// that fit the respective VFS addon and allow special operations.
+ ///
+ /// @note This procedure is not yet standardized and is currently not
+ /// exactly available which are handed over.
+ std::string GetOptions() const { return m_cStructure->options; }
+
+ /// @brief Desired username.
+ std::string GetUsername() const { return m_cStructure->username; }
+
+ /// @brief Desired password.
+ std::string GetPassword() const { return m_cStructure->password; }
+
+ /// @brief The complete URL is passed on here, but the user name and
+ /// password are not shown and only appear to there as `USERNAME:PASSWORD`.
+ ///
+ /// As example <b>`sftp://USERNAME:PASSWORD@192.168.178.123/storage/videos/00001.ts`</b>.
+ std::string GetRedacted() const { return m_cStructure->redacted; }
+
+ /// @brief The name which is taken as the basis by source and would be first
+ /// in folder view.
+ ///
+ /// As example on <b>`sftp://dudu:isprivate@192.168.178.123/storage/videos/00001.ts`</b>
+ /// becomes then <b>`storage`</b> used here.
+ std::string GetSharename() const { return m_cStructure->sharename; }
+
+ /// @brief Protocol name used on this stream, e.g. <b>`sftp`</b>.
+ std::string GetProtocol() const { return m_cStructure->protocol; }
+
+ ///@}
+
+private:
+ VFSUrl() = delete;
+ VFSUrl(const VFSUrl& channel) = delete;
+ VFSUrl(const VFSURL* channel) : CStructHdl(channel) {}
+ VFSUrl(VFSURL* channel) : CStructHdl(channel) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_vfs_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_vfs
+/// @brief **VFS add-on general variables**
+///
+/// Used to exchange the available options between Kodi and addon.
+///
+///
+
+//==============================================================================
+///
+/// @addtogroup cpp_kodi_addon_vfs
+/// @brief \cpp_class{ kodi::addon::CInstanceVFS }
+/// **Virtual Filesystem (VFS) add-on instance**
+///
+/// This instance type is used to allow Kodi various additional file system
+/// types. Be it a special file system, a compressed package or a system
+/// available over the network, everything is possible with it.
+///
+/// This usage can be requested under various conditions, for example explicitly
+/// by another addon, by a Mimetype protocol defined in <b>`addon.xml`</b> or supported
+/// file extensions.
+///
+/// Include the header @ref VFS.h "#include <kodi/addon-instance/VFS.h>"
+/// to use this class.
+///
+/// ----------------------------------------------------------------------------
+///
+/// Here is an example of what the <b>`addon.xml.in`</b> would look like for an VFS addon:
+///
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="vfs.myspecialnamefor"
+/// version="1.0.0"
+/// name="My VFS addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="kodi.vfs"
+/// protocols="myprot"
+/// extensions=".abc|.def"
+/// files="true"
+/// filedirectories="true"
+/// directories="true"
+/// encodedhostname="true"
+/// supportDialog="true"
+/// supportPath="true"
+/// supportUsername="true"
+/// supportPassword="true"
+/// supportPort="true"
+/// supportBrowsing="true"
+/// supportWrite="true"
+/// defaultPort="1234"
+/// label="30000"
+/// zeroconf="your_special_zeroconf_allowed_identifier"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My VFS addon summary</summary>
+/// <description lang="en_GB">My VFS description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+/// @note Regarding boolean values with "false", these can also be omitted,
+/// since this would be the default.
+///
+///
+/// ### Standard values that can be declared for processing in `addon.xml`.
+///
+/// These values are used by Kodi to identify associated streams and file
+/// extensions and then to select the associated addon.
+///
+/// \table_start
+/// \table_h3{ Labels, Type, Description }
+/// \table_row3{ <b>`point`</b>,
+/// \anchor cpp_kodi_addon_vfs_point
+/// string,
+/// The identification of the addon instance to VFS is mandatory <b>`kodi.vfs`</b>.
+/// In addition\, the instance declared in the first <b>`<extension ... />`</b> is also the main type of addon.
+/// }
+/// \table_row3{ <b>`defaultPort`</b>,
+/// \anchor cpp_kodi_addon_vfs_defaultPort
+/// integer,
+/// Default [networking port](https://en.wikipedia.org/wiki/Port_(computer_networking))
+/// to use for protocol.
+/// }
+/// \table_row3{ <b>`directories`</b>,
+/// \anchor cpp_kodi_addon_vfs_directories
+/// boolean,
+/// VFS entry can list directories.
+/// }
+/// \table_row3{ <b>`extensions`</b>,
+/// \anchor cpp_kodi_addon_vfs_extensions
+/// string,
+/// Extensions for VFS entry.\n
+/// It is possible to declare several using <b>`|`</b>\, e.g. <b>`.abc|.def|.ghi`</b>.
+/// }
+/// \table_row3{ <b>`encodedhostname`</b>,
+/// \anchor cpp_kodi_addon_vfs_encodedhostname
+/// boolean,
+/// URL protocol from add-ons use encoded hostnames.
+/// }
+/// \table_row3{ <b>`filedirectories`</b>,
+/// \anchor cpp_kodi_addon_vfs_filedirectories
+/// boolean,
+/// VFS entry contains file directories.
+/// }
+/// \table_row3{ <b>`files`</b>,
+/// \anchor cpp_kodi_addon_vfs_directories
+/// boolean,
+/// Set to declare that VFS provides files.
+/// }
+/// \table_row3{ <b>`protocols`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocols
+/// boolean,
+/// Protocols for VFS entry.\n
+/// It is possible to declare several using <b>`|`</b>\, e.g. <b>`myprot1|myprot2`</b>.\n
+/// @note This field also used to show on GUI\, see <b>`supportBrowsing`</b> below about <b>*2:</b>.
+/// When used there\, however\, only a **single** protocol is possible!
+/// }
+/// \table_row3{ <b>`supportWrite`</b>,
+/// \anchor cpp_kodi_addon_vfs_supportWrite
+/// boolean,
+/// Protocol supports write operations.
+/// }
+/// \table_row3{ <b>`zeroconf`</b>,
+/// \anchor cpp_kodi_addon_vfs_zeroconf
+/// string,
+/// [Zero conf](https://en.wikipedia.org/wiki/Zero-configuration_networking) announce string for VFS protocol.
+/// }
+/// \table_row3{ <b>`library_@PLATFORM@`</b>,
+/// \anchor cpp_kodi_addon_vfs_library
+/// string,
+/// The runtime library used for the addon. This is usually declared by `cmake` and correctly displayed in the translated <b>`addon.xml`</b>.
+/// }
+/// \table_end
+///
+///
+/// ### User selectable parts of the addon.
+///
+/// The following table describes the values that can be defined by <b>`addon.xml`</b>
+/// and which part they relate to for user input.
+///
+/// \table_start
+/// \table_h3{ Labels, Type, Description }
+/// \table_row3{ <b>`supportBrowsing`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_supportBrowsing
+/// boolean,
+/// Protocol supports server browsing. Used to open related sources by users in the window.\n\n
+/// | Associated places in Kodi: |
+/// | :---- |
+/// | \image html cpp_kodi_addon_vfs_protocol_1.png |
+/// <br>
+/// <b>*1:</b> The entry in the menu represented by this option corresponds to the text given with <b>`label`</b>.
+/// When the button is pressed\, @ref CInstanceVFS::GetDirectory is called on the add-on to get its content.\n
+/// <b>*2:</b> Protocol name of the stream defined with <b>`protocols`</b> in xml.\n
+/// @remark See also <b>`supportDialog`</b> about <b>*3:</b>.
+/// }
+/// \table_row3{ <b>`supportDialog`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_supportDialog
+/// boolean,
+/// To point out that Kodi assigns a dialog to this VFS in order to compare it with other values e.g. query supportPassword in it.\n
+/// This will be available when adding sources in Kodi under <b>"Add network location..."</b>.\n\n
+/// | Associated places in Kodi: |
+/// | :---- |
+/// | \image html cpp_kodi_addon_vfs_protocol_2.png |
+/// <br>
+/// <b>*1:</b> Field for selecting the VFS handler\, the addon will be available if <b>`supportDialog`</b> is set to <b>`true`</b>.\n
+/// <b>*2:</b> To set the associated server address. **Note:** *This field is always activated and cannot be changed by the addon.*\n
+/// <b>*3:</b> If <b>`supportBrowsing`</b> is set to <b>`true`</b>\, the button for opening a file selection dialog is given here too\, as in the file window.\n
+/// <b>*4:</b> This field is available if <b>`supportPath`</b> is set to <b>`true`</b>.\n
+/// <b>*5:</b> To edit the connection port. This field is available if <b>`supportPort`</b> is set to <b>`true`</b>.\n
+/// <b>*6:</b> This sets the required username and is available when <b>`supportUsername`</b> is set to <b>`true`</b>.\n
+/// <b>*7:</b> This sets the required password and is available when <b>`supportPassword`</b> is set to <b>`true`</b>.
+/// }
+/// \table_row3{ <b>`supportPath`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_supportPath
+/// boolean,
+/// Protocol has path in addition to server name (see <b>`supportDialog`</b> about <b>*4:</b>).
+/// }
+/// \table_row3{ <b>`supportPort`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_supportPort
+/// boolean,
+/// Protocol supports port customization (see <b>`supportDialog`</b> about <b>*5:</b>).
+/// }
+/// \table_row3{ <b>`supportUsername`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_supportUsername
+/// boolean,
+/// Protocol uses logins (see <b>`supportDialog`</b> about <b>*6:</b>).
+/// }
+/// \table_row3{ <b>`supportPassword`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_supportPassword
+/// boolean,
+/// Protocol supports passwords (see <b>`supportDialog`</b> about <b>*7:</b>).
+/// }
+/// \table_row3{ <b>`protocols`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_protocols
+/// string,
+/// Protocols for VFS entry.
+/// @note This field is not editable and only used on GUI to show his name\, see <b>`supportBrowsing`</b> about <b>*2:</b>
+/// }
+/// \table_row3{ <b>`label`</b>,
+/// \anchor cpp_kodi_addon_vfs_protocol_label
+/// integer,
+/// The text identification number used in Kodi for display in the menu at <b>`supportDialog`</b>
+/// as a selection option and at <b>`supportBrowsing`</b> (see his image reference <b>*1</b>) as a menu entry.\n
+/// This can be a text identifier in Kodi or from addon.\n
+/// @remark For addon within <b>30000</b>-<b>30999</b> or <b>32000</b>-<b>32999</b>.
+/// }
+/// \table_end
+///
+/// @remark For more detailed description of the <b>`addon.xml`</b>, see also https://kodi.wiki/view/Addon.xml.
+///
+///
+/// --------------------------------------------------------------------------
+///
+///
+/// **Example:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/VFS.h>
+///
+/// class CMyVFS : public kodi::addon::CInstanceVFS
+/// {
+/// public:
+/// CMyVFS(const kodi::addon::IInstanceInfo& instance);
+///
+/// // Add all your required functions, the most CInstanceVFS functions of
+/// // must be included to have addon working correctly.
+/// ...
+/// };
+///
+/// CMyVFS::CMyVFS(const kodi::addon::IInstanceInfo& instance)
+/// : kodi::addon::CInstanceVFS(instance)
+/// {
+/// ...
+/// }
+///
+/// ...
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_VFS))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my VFS instance");
+/// hdl = new CMyVFS(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyVFS` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+//------------------------------------------------------------------------------
+class ATTR_DLL_LOCAL CInstanceVFS : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs
+ /// @brief VFS class constructor used to support multiple instance
+ /// types
+ ///
+ /// @param[in] instance The instance value given to <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>.
+ ///
+ /// @note Instance path as a single is not supported by this type. It must
+ /// ensure that it can be called up several times.
+ ///
+ /// @warning Only use `instance` from the @ref CAddonBase::CreateInstance call.
+ ///
+ explicit CInstanceVFS(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceVFS: Creation of multiple together with single "
+ "instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs
+ /// @brief Destructor
+ ///
+ ~CInstanceVFS() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_vfs_general 1. General access functions
+ /// @ingroup cpp_kodi_addon_vfs
+ /// @brief **General access functions**
+ ///
+ /// This functions which are intended for getting folders, editing storage
+ /// locations and file system queries.
+ ///
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_vfs_filecontrol 2. File editing functions
+ /// @ingroup cpp_kodi_addon_vfs
+ /// @brief **File editing functions.**
+ ///
+ /// This value represents the addon-side handlers and to be able to identify
+ /// his own parts in the event of further access.
+ ///
+
+ //@{
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Open a file for input
+ ///
+ /// @param[in] url The URL of the file
+ /// @return Context for the opened file
+ ///
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_vfs_Defs_VFSUrl_Help
+ ///
+ virtual kodi::addon::VFSFileHandle Open(const kodi::addon::VFSUrl& url) { return nullptr; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Open a file for output
+ ///
+ /// @param[in] url The URL of the file
+ /// @param[in] overWrite Whether or not to overwrite an existing file
+ /// @return Context for the opened file
+ ///
+ virtual kodi::addon::VFSFileHandle OpenForWrite(const kodi::addon::VFSUrl& url, bool overWrite)
+ {
+ return nullptr;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Close a file
+ ///
+ /// @param[in] context The context of the file
+ /// @return True on success, false on failure
+ ///
+ virtual bool Close(kodi::addon::VFSFileHandle context) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Read from a file
+ ///
+ /// @param[in] context The context of the file
+ /// @param[out] buffer The buffer to read data into
+ /// @param[in] uiBufSize Number of bytes to read
+ /// @return Number of bytes read
+ ///
+ virtual ssize_t Read(kodi::addon::VFSFileHandle context, uint8_t* buffer, size_t uiBufSize)
+ {
+ return -1;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Write to a file
+ ///
+ /// @param[in] context The context of the file
+ /// @param[in] buffer The buffer to read data from
+ /// @param[in] uiBufSize Number of bytes to write
+ /// @return Number of bytes written
+ ///
+ virtual ssize_t Write(kodi::addon::VFSFileHandle context, const uint8_t* buffer, size_t uiBufSize)
+ {
+ return -1;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Seek in a file
+ ///
+ /// @param[in] context The context of the file
+ /// @param[in] position The position to seek to
+ /// @param[in] whence Position in file 'position' is relative to (SEEK_CUR, SEEK_SET, SEEK_END):
+ /// | Value | int | Description |
+ /// |:--------:|:---:|:----------------------------------------------------|
+ /// | SEEK_SET | 0 | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
+ /// | SEEK_CUR | 1 | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
+ /// | SEEK_END | 2 | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
+ /// @return Offset in file after seek
+ ///
+ virtual int64_t Seek(kodi::addon::VFSFileHandle context, int64_t position, int whence)
+ {
+ return -1;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Truncate a file
+ ///
+ /// @param[in] context The context of the file
+ /// @param[in] size The size to truncate the file to
+ /// @return 0 on success, -1 on error
+ ///
+ virtual int Truncate(kodi::addon::VFSFileHandle context, int64_t size) { return -1; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Get total size of a file
+ ///
+ /// @param[in] context The context of the file
+ /// @return Total file size
+ ///
+ virtual int64_t GetLength(kodi::addon::VFSFileHandle context) { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Get current position in a file
+ ///
+ /// @param[in] context The context of the file
+ /// @return Current position
+ ///
+ virtual int64_t GetPosition(kodi::addon::VFSFileHandle context) { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Get chunk size of a file
+ ///
+ /// @param[in] context The context of the file
+ /// @return Chunk size
+ ///
+ virtual int GetChunkSize(kodi::addon::VFSFileHandle context) { return 1; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief To check seek possible on current stream by file.
+ ///
+ /// @return true if seek possible, false if not
+ ///
+ virtual bool IoControlGetSeekPossible(kodi::addon::VFSFileHandle context) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief To check a running stream on file for state of his cache.
+ ///
+ /// @param[in] status Information about current cache status
+ /// @return true if successfully done, false otherwise
+ ///
+ ///
+ /// @copydetails cpp_kodi_vfs_Defs_CacheStatus_Help
+ ///
+ virtual bool IoControlGetCacheStatus(kodi::addon::VFSFileHandle context,
+ kodi::vfs::CacheStatus& status)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Unsigned int with speed limit for caching in bytes per second.
+ ///
+ /// @param[in] rate Cache rate size to use
+ /// @return true if successfully done, false otherwise
+ ///
+ virtual bool IoControlSetCacheRate(kodi::addon::VFSFileHandle context, uint32_t rate)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_filecontrol
+ /// @brief Enable/disable retry within the protocol handler (if supported).
+ ///
+ /// @param[in] retry To set the retry, true for use, false for not
+ /// @return true if successfully done, false otherwise
+ ///
+ virtual bool IoControlSetRetry(kodi::addon::VFSFileHandle context, bool retry) { return false; }
+ //----------------------------------------------------------------------------
+ //@}
+
+ //@{
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Stat a file
+ ///
+ /// @param[in] url The URL of the file
+ /// @param[in] buffer The buffer to store results in
+ /// @return -1 on error, 0 otherwise
+ ///
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_vfs_Defs_VFSUrl_Help
+ ///
+ virtual int Stat(const kodi::addon::VFSUrl& url, kodi::vfs::FileStatus& buffer) { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Check for file existence
+ ///
+ /// @param[in] url The URL of the file
+ /// @return True if file exists, false otherwise
+ ///
+ virtual bool Exists(const kodi::addon::VFSUrl& url) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Clear out any idle connections
+ ///
+ virtual void ClearOutIdle() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Disconnect all connections
+ ///
+ virtual void DisconnectAll() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Delete a file
+ ///
+ /// @param[in] url The URL of the file
+ /// @return True if deletion was successful, false otherwise
+ ///
+ virtual bool Delete(const kodi::addon::VFSUrl& url) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Rename a file
+ ///
+ /// @param[in] url The URL of the source file
+ /// @param[in] url2 The URL of the destination file
+ /// @return True if deletion was successful, false otherwise
+ ///
+ virtual bool Rename(const kodi::addon::VFSUrl& url, const kodi::addon::VFSUrl& url2)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Check for directory existence
+ ///
+ /// @param[in] url The URL of the file
+ /// @return True if directory exists, false otherwise
+ ///
+ virtual bool DirectoryExists(const kodi::addon::VFSUrl& url) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Remove a directory
+ ///
+ /// @param[in] url The URL of the directory
+ /// @return True if removal was successful, false otherwise
+ ///
+ virtual bool RemoveDirectory(const kodi::addon::VFSUrl& url) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Create a directory
+ ///
+ /// @param[in] url The URL of the file
+ /// @return True if creation was successful, false otherwise
+ ///
+ virtual bool CreateDirectory(const kodi::addon::VFSUrl& url) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_vfs_general_cb_GetDirectory Callbacks GetDirectory()
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Callback functions on GetDirectory()
+ ///
+ /// This functions becomes available during call of GetDirectory() from
+ /// Kodi.
+ ///
+ /// If GetDirectory() returns false becomes the parts from here used on
+ /// next call of the function.
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ ///
+ /// #include <kodi/addon-instance/VFS.h>
+ ///
+ /// ...
+ ///
+ /// bool CMyVFS::GetDirectory(const kodi::addon::VFSUrl& url,
+ /// std::vector<kodi::vfs::CDirEntry>& items,
+ /// CVFSCallbacks callbacks)
+ /// {
+ /// std::string neededString;
+ /// callbacks.GetKeyboardInput("Test", neededString, true);
+ /// if (neededString.empty())
+ /// return false;
+ ///
+ /// // Do the work
+ /// ...
+ /// return true;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ class CVFSCallbacks
+ {
+ public:
+ /// @ingroup cpp_kodi_addon_vfs_general_cb_GetDirectory
+ /// @brief Require keyboard input
+ ///
+ /// Becomes called if GetDirectory() returns false and GetDirectory()
+ /// becomes after entry called again.
+ ///
+ /// @param[in] heading The heading of the keyboard dialog
+ /// @param[out] input The resulting string. Returns string after
+ /// second call!
+ /// @param[in] hiddenInput To show input only as "*" on dialog
+ /// @return True if input was received, false otherwise
+ ///
+ bool GetKeyboardInput(const std::string& heading, std::string& input, bool hiddenInput = false)
+ {
+ char* cInput = nullptr;
+ bool ret = m_cb->get_keyboard_input(m_cb->ctx, heading.c_str(), &cInput, hiddenInput);
+ if (cInput)
+ {
+ input = cInput;
+ ::kodi::addon::CPrivateBase::m_interface->toKodi->free_string(
+ ::kodi::addon::CPrivateBase::m_interface->toKodi->kodiBase, cInput);
+ }
+ return ret;
+ }
+
+ /// @ingroup cpp_kodi_addon_vfs_general_cb_GetDirectory
+ /// @brief Display an error dialog
+ ///
+ /// @param[in] heading The heading of the error dialog
+ /// @param[in] line1 The first line of the error dialog
+ /// @param[in] line2 [opt] The second line of the error dialog
+ /// @param[in] line3 [opt] The third line of the error dialog
+ ///
+ void SetErrorDialog(const std::string& heading,
+ const std::string& line1,
+ const std::string& line2 = "",
+ const std::string& line3 = "")
+ {
+ m_cb->set_error_dialog(m_cb->ctx, heading.c_str(), line1.c_str(), line2.c_str(),
+ line3.c_str());
+ }
+
+ /// @ingroup cpp_kodi_addon_vfs_general_cb_GetDirectory
+ /// @brief Prompt the user for authentication of a URL
+ ///
+ /// @param[in] url The URL
+ void RequireAuthentication(const std::string& url)
+ {
+ m_cb->require_authentication(m_cb->ctx, url.c_str());
+ }
+
+ explicit CVFSCallbacks(const VFSGetDirectoryCallbacks* cb) : m_cb(cb) {}
+
+ private:
+ const VFSGetDirectoryCallbacks* m_cb;
+ };
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief List a directory
+ ///
+ /// @param[in] url The URL of the directory
+ /// @param[out] entries The entries in the directory, see
+ /// @ref cpp_kodi_vfs_CDirEntry "kodi::vfs::CDirEntry"
+ /// about his content
+ /// @param[in] callbacks A callback structure
+ /// @return Context for the directory listing
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// ### Callbacks:
+ /// @copydetails cpp_kodi_addon_vfs_general_cb_GetDirectory
+ ///
+ /// **Available callback functions**
+ /// | Function: | Description
+ /// |--|--
+ /// | CVFSCallbacks::GetKeyboardInput | @copybrief CVFSCallbacks::GetKeyboardInput @copydetails CVFSCallbacks::GetKeyboardInput
+ /// | CVFSCallbacks::SetErrorDialog | @copybrief CVFSCallbacks::SetErrorDialog @copydetails CVFSCallbacks::SetErrorDialog
+ /// | CVFSCallbacks::RequireAuthentication | @copybrief CVFSCallbacks::RequireAuthentication @copydetails CVFSCallbacks::RequireAuthentication
+ ///
+ virtual bool GetDirectory(const kodi::addon::VFSUrl& url,
+ std::vector<kodi::vfs::CDirEntry>& entries,
+ CVFSCallbacks callbacks)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_vfs_general
+ /// @brief Check if file should be presented as a directory (multiple streams)
+ ///
+ /// @param[in] url The URL of the file
+ /// @param[out] entries The entries in the directory, see
+ /// @ref cpp_kodi_vfs_CDirEntry "kodi::vfs::CDirEntry"
+ /// about his content
+ /// @param[out] rootPath Path to root directory if multiple entries
+ /// @return Context for the directory listing
+ ///
+ virtual bool ContainsFiles(const kodi::addon::VFSUrl& url,
+ std::vector<kodi::vfs::CDirEntry>& entries,
+ std::string& rootPath)
+ {
+ return false;
+ }
+ //----------------------------------------------------------------------------
+ //@}
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ m_instanceData = instance;
+ m_instanceData->hdl = this;
+ m_instanceData->vfs->toAddon->addonInstance = this;
+ m_instanceData->vfs->toAddon->open = ADDON_Open;
+ m_instanceData->vfs->toAddon->open_for_write = ADDON_OpenForWrite;
+ m_instanceData->vfs->toAddon->read = ADDON_Read;
+ m_instanceData->vfs->toAddon->write = ADDON_Write;
+ m_instanceData->vfs->toAddon->seek = ADDON_Seek;
+ m_instanceData->vfs->toAddon->truncate = ADDON_Truncate;
+ m_instanceData->vfs->toAddon->get_length = ADDON_GetLength;
+ m_instanceData->vfs->toAddon->get_position = ADDON_GetPosition;
+ m_instanceData->vfs->toAddon->get_chunk_size = ADDON_GetChunkSize;
+ m_instanceData->vfs->toAddon->io_control_get_seek_possible = ADDON_IoControlGetSeekPossible;
+ m_instanceData->vfs->toAddon->io_control_get_cache_status = ADDON_IoControlGetCacheStatus;
+ m_instanceData->vfs->toAddon->io_control_set_cache_rate = ADDON_IoControlSetCacheRate;
+ m_instanceData->vfs->toAddon->io_control_set_retry = ADDON_IoControlSetRetry;
+ m_instanceData->vfs->toAddon->stat = ADDON_Stat;
+ m_instanceData->vfs->toAddon->close = ADDON_Close;
+ m_instanceData->vfs->toAddon->exists = ADDON_Exists;
+ m_instanceData->vfs->toAddon->clear_out_idle = ADDON_ClearOutIdle;
+ m_instanceData->vfs->toAddon->disconnect_all = ADDON_DisconnectAll;
+ m_instanceData->vfs->toAddon->delete_it = ADDON_Delete;
+ m_instanceData->vfs->toAddon->rename = ADDON_Rename;
+ m_instanceData->vfs->toAddon->directory_exists = ADDON_DirectoryExists;
+ m_instanceData->vfs->toAddon->remove_directory = ADDON_RemoveDirectory;
+ m_instanceData->vfs->toAddon->create_directory = ADDON_CreateDirectory;
+ m_instanceData->vfs->toAddon->get_directory = ADDON_GetDirectory;
+ m_instanceData->vfs->toAddon->free_directory = ADDON_FreeDirectory;
+ m_instanceData->vfs->toAddon->contains_files = ADDON_ContainsFiles;
+ }
+
+ inline static VFS_FILE_HANDLE ADDON_Open(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Open(url);
+ }
+
+ inline static VFS_FILE_HANDLE ADDON_OpenForWrite(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url,
+ bool overWrite)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->OpenForWrite(url, overWrite);
+ }
+
+ inline static ssize_t ADDON_Read(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ uint8_t* buffer,
+ size_t uiBufSize)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->Read(context, buffer, uiBufSize);
+ }
+
+ inline static ssize_t ADDON_Write(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ const uint8_t* buffer,
+ size_t uiBufSize)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->Write(context, buffer, uiBufSize);
+ }
+
+ inline static int64_t ADDON_Seek(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ int64_t position,
+ int whence)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->Seek(context, position, whence);
+ }
+
+ inline static int ADDON_Truncate(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ int64_t size)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Truncate(context, size);
+ }
+
+ inline static int64_t ADDON_GetLength(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->GetLength(context);
+ }
+
+ inline static int64_t ADDON_GetPosition(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->GetPosition(context);
+ }
+
+ inline static int ADDON_GetChunkSize(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->GetChunkSize(context);
+ }
+
+ inline static bool ADDON_IoControlGetSeekPossible(const AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->IoControlGetSeekPossible(context);
+ }
+
+ inline static bool ADDON_IoControlGetCacheStatus(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ VFS_CACHE_STATUS_DATA* status)
+ {
+ kodi::vfs::CacheStatus cppStatus(status);
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->IoControlGetCacheStatus(context, cppStatus);
+ }
+
+ inline static bool ADDON_IoControlSetCacheRate(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ uint32_t rate)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->IoControlSetCacheRate(context, rate);
+ }
+
+ inline static bool ADDON_IoControlSetRetry(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ bool retry)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->IoControlSetRetry(context, retry);
+ }
+
+ inline static int ADDON_Stat(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url,
+ struct STAT_STRUCTURE* buffer)
+ {
+ kodi::vfs::FileStatus cppBuffer(buffer);
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Stat(url, cppBuffer);
+ }
+
+ inline static bool ADDON_Close(const AddonInstance_VFSEntry* instance, VFS_FILE_HANDLE context)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Close(context);
+ }
+
+ inline static bool ADDON_Exists(const AddonInstance_VFSEntry* instance, const VFSURL* url)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Exists(url);
+ }
+
+ inline static void ADDON_ClearOutIdle(const AddonInstance_VFSEntry* instance)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->ClearOutIdle();
+ }
+
+ inline static void ADDON_DisconnectAll(const AddonInstance_VFSEntry* instance)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->DisconnectAll();
+ }
+
+ inline static bool ADDON_Delete(const AddonInstance_VFSEntry* instance, const VFSURL* url)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Delete(url);
+ }
+
+ inline static bool ADDON_Rename(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url,
+ const VFSURL* url2)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Rename(url, url2);
+ }
+
+ inline static bool ADDON_DirectoryExists(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->DirectoryExists(url);
+ }
+
+ inline static bool ADDON_RemoveDirectory(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->RemoveDirectory(url);
+ }
+
+ inline static bool ADDON_CreateDirectory(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url)
+ {
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->CreateDirectory(url);
+ }
+
+ inline static bool ADDON_GetDirectory(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url,
+ VFSDirEntry** retEntries,
+ int* num_entries,
+ VFSGetDirectoryCallbacks* callbacks)
+ {
+ std::vector<kodi::vfs::CDirEntry> addonEntries;
+ bool ret = static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->GetDirectory(url, addonEntries, CVFSCallbacks(callbacks));
+ if (ret)
+ {
+ VFSDirEntry* entries =
+ static_cast<VFSDirEntry*>(malloc(sizeof(VFSDirEntry) * addonEntries.size()));
+ for (unsigned int i = 0; i < addonEntries.size(); ++i)
+ {
+ entries[i].label = strdup(addonEntries[i].Label().c_str());
+ entries[i].title = strdup(addonEntries[i].Title().c_str());
+ entries[i].path = strdup(addonEntries[i].Path().c_str());
+ entries[i].folder = addonEntries[i].IsFolder();
+ entries[i].size = addonEntries[i].Size();
+ entries[i].date_time = addonEntries[i].DateTime();
+
+ entries[i].num_props = 0;
+ const std::map<std::string, std::string>& props = addonEntries[i].GetProperties();
+ if (!props.empty())
+ {
+ entries[i].properties =
+ static_cast<VFSProperty*>(malloc(sizeof(VFSProperty) * props.size()));
+ for (const auto& prop : props)
+ {
+ entries[i].properties[entries[i].num_props].name = strdup(prop.first.c_str());
+ entries[i].properties[entries[i].num_props].val = strdup(prop.second.c_str());
+ ++entries[i].num_props;
+ }
+ }
+ else
+ entries[i].properties = nullptr;
+ }
+ *retEntries = entries;
+ *num_entries = static_cast<int>(addonEntries.size());
+ }
+ return ret;
+ }
+
+ inline static void ADDON_FreeDirectory(const AddonInstance_VFSEntry* instance,
+ VFSDirEntry* entries,
+ int num_entries)
+ {
+ for (int i = 0; i < num_entries; ++i)
+ {
+ if (entries[i].properties)
+ {
+ for (unsigned int j = 0; j < entries[i].num_props; ++j)
+ {
+ free(entries[i].properties[j].name);
+ free(entries[i].properties[j].val);
+ }
+ free(entries[i].properties);
+ }
+ free(entries[i].label);
+ free(entries[i].title);
+ free(entries[i].path);
+ }
+ free(entries);
+ }
+
+ inline static bool ADDON_ContainsFiles(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url,
+ VFSDirEntry** retEntries,
+ int* num_entries,
+ char* rootpath)
+ {
+ std::string cppRootPath;
+ std::vector<kodi::vfs::CDirEntry> addonEntries;
+ bool ret = static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
+ ->ContainsFiles(url, addonEntries, cppRootPath);
+ if (ret)
+ {
+ strncpy(rootpath, cppRootPath.c_str(), ADDON_STANDARD_STRING_LENGTH);
+
+ VFSDirEntry* entries =
+ static_cast<VFSDirEntry*>(malloc(sizeof(VFSDirEntry) * addonEntries.size()));
+ for (size_t i = 0; i < addonEntries.size(); ++i)
+ {
+ entries[i].label = strdup(addonEntries[i].Label().c_str());
+ entries[i].title = strdup(addonEntries[i].Title().c_str());
+ entries[i].path = strdup(addonEntries[i].Path().c_str());
+ entries[i].folder = addonEntries[i].IsFolder();
+ entries[i].size = addonEntries[i].Size();
+ entries[i].date_time = addonEntries[i].DateTime();
+
+ entries[i].num_props = 0;
+ const std::map<std::string, std::string>& props = addonEntries[i].GetProperties();
+ if (!props.empty())
+ {
+ entries[i].properties =
+ static_cast<VFSProperty*>(malloc(sizeof(VFSProperty) * props.size()));
+ for (const auto& prop : props)
+ {
+ entries[i].properties[entries[i].num_props].name = strdup(prop.first.c_str());
+ entries[i].properties[entries[i].num_props].val = strdup(prop.second.c_str());
+ ++entries[i].num_props;
+ }
+ }
+ else
+ entries[i].properties = nullptr;
+ }
+ *retEntries = entries;
+ *num_entries = static_cast<int>(addonEntries.size());
+ }
+ return ret;
+ }
+
+ KODI_ADDON_INSTANCE_STRUCT* m_instanceData{nullptr};
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VideoCodec.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VideoCodec.h
new file mode 100644
index 0000000..06f0fc8
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VideoCodec.h
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2017-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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/addon-instance/video_codec.h"
+#include "inputstream/DemuxPacket.h"
+#include "inputstream/StreamCodec.h"
+#include "inputstream/StreamCrypto.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+class CInstanceVideoCodec;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata class VideoCodecInitdata
+/// @ingroup cpp_kodi_addon_videocodec_Defs
+/// @brief Initialization data to open a video codec stream.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata_Help
+///
+///@{
+class ATTR_DLL_LOCAL VideoCodecInitdata : public CStructHdl<VideoCodecInitdata, VIDEOCODEC_INITDATA>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceVideoCodec;
+ /*! \endcond */
+
+public:
+ /// @defgroup cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata_Help Value Help
+ /// @ingroup cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata :</b>
+ /// | Name | Type | Get call
+ /// |------|------|----------
+ /// | **Codec type** | `VIDEOCODEC_TYPE` | @ref VideoCodecInitdata::GetCodecType "GetCodecType"
+ /// | **Codec profile** | `STREAMCODEC_PROFILE` | @ref VideoCodecInitdata::GetCodecProfile "GetCodecProfile"
+ /// | **Video formats** | `std::vector<VIDEOCODEC_FORMAT>` | @ref VideoCodecInitdata::GetVideoFormats "GetVideoFormats"
+ /// | **Width** | `uint32_t` | @ref VideoCodecInitdata::GetWidth "GetWidth"
+ /// | **Height** | `uint32_t` | @ref VideoCodecInitdata::GetHeight "GetHeight"
+ /// | **Extra data** | `const uint8_t*` | @ref VideoCodecInitdata::GetExtraData "GetExtraData"
+ /// | **Extra data size** | `unsigned int` | @ref VideoCodecInitdata::GetExtraDataSize "GetExtraDataSize"
+ /// | **Crypto session** | `kodi::addon::StreamCryptoSession` | @ref VideoCodecInitdata::GetCryptoSession "GetCryptoSession"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata
+ ///@{
+
+ /// @brief The codec type required by Kodi to process the stream.
+ ///
+ /// See @ref VIDEOCODEC_TYPE for possible values.
+ VIDEOCODEC_TYPE GetCodecType() const { return m_cStructure->codec; }
+
+ /// @brief Used profiles for non-scalable 2D video
+ STREAMCODEC_PROFILE GetCodecProfile() const { return m_cStructure->codecProfile; }
+
+ /// @brief The video stream representations requested by Kodi
+ ///
+ /// This contains a list of the required video formats. One of them has to
+ /// select the addon to return the created image.
+ ///
+ std::vector<VIDEOCODEC_FORMAT> GetVideoFormats() const
+ {
+ std::vector<VIDEOCODEC_FORMAT> formats;
+ unsigned int i = 0;
+ while (i < VIDEOCODEC_FORMAT_MAXFORMATS &&
+ m_cStructure->videoFormats[i] != VIDEOCODEC_FORMAT_UNKNOWN)
+ formats.emplace_back(m_cStructure->videoFormats[i++]);
+ if (formats.empty())
+ formats.emplace_back(VIDEOCODEC_FORMAT_UNKNOWN);
+ return formats;
+ }
+
+ /// @brief Picture width.
+ uint32_t GetWidth() const { return m_cStructure->width; }
+
+ /// @brief Picture height.
+ uint32_t GetHeight() const { return m_cStructure->height; }
+
+ /// @brief Depending on the required decoding, additional data given by the stream.
+ const uint8_t* GetExtraData() const { return m_cStructure->extraData; }
+
+ /// @brief Size of the data given with @ref extraData.
+ unsigned int GetExtraDataSize() const { return m_cStructure->extraDataSize; }
+
+ /// @brief **Data to manage stream cryptography**\n
+ /// To get class structure manages any encryption values required in order to have
+ /// them available in their stream processing.
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_inputstream_Defs_Info_StreamCryptoSession_Help
+ ///
+ kodi::addon::StreamCryptoSession GetCryptoSession() const { return &m_cStructure->cryptoSession; }
+
+ ///@}
+
+private:
+ VideoCodecInitdata() = delete;
+ VideoCodecInitdata(const VideoCodecInitdata& session) : CStructHdl(session) {}
+ VideoCodecInitdata(const VIDEOCODEC_INITDATA* session) : CStructHdl(session) {}
+ VideoCodecInitdata(VIDEOCODEC_INITDATA* session) : CStructHdl(session) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//##############################################################################
+/// @defgroup cpp_kodi_addon_videocodec_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_videocodec
+/// @brief **Video codec add-on general variables**
+///
+/// Used to exchange the available options between Kodi and addon.
+///
+///
+
+//============================================================================
+///
+/// @addtogroup cpp_kodi_addon_videocodec
+/// @brief \cpp_class{ kodi::addon::CInstanceVideoCodec }
+/// **Video codec add-on instance**
+///
+/// This is an addon instance class to add an additional video decoder to Kodi
+/// using addon.
+///
+/// This means that either a new type of decoding can be introduced to an input
+/// stream add-on that requires special types of decoding.
+///
+/// When using the inputstream addon, @ref cpp_kodi_addon_inputstream_Defs_Interface_InputstreamInfo
+/// to @ref cpp_kodi_addon_inputstream_Defs_Info is used to declare that the
+/// decoder stored in the addon is used.
+///
+/// @note At the moment this can only be used together with input stream addons,
+/// independent use as a codec addon is not yet possible.
+///
+/// Include the header @ref VideoCodec.h "#include <kodi/addon-instance/VideoCodec.h>"
+/// to use this class.
+///
+/// --------------------------------------------------------------------------
+///
+/// **Example:**
+/// This as an example when used together with @ref cpp_kodi_addon_inputstream "kodi::addon::CInstanceInputStream".
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/Inputstream.h>
+/// #include <kodi/addon-instance/VideoCodec.h>
+///
+/// class CMyVideoCodec : public kodi::addon::CInstanceVideoCodec
+/// {
+/// public:
+/// CMyVideoCodec(const kodi::addon::IInstanceInfo& instance,
+/// CMyInputstream* inputstream);
+/// ...
+///
+/// private:
+/// CMyInputstream* m_inputstream;
+/// };
+///
+/// CMyVideoCodec::CMyVideoCodec(const kodi::addon::IInstanceInfo& instance,
+/// CMyInputstream* inputstream)
+/// : kodi::addon::CInstanceVideoCodec(instance),
+/// m_inputstream(inputstream)
+/// {
+/// ...
+/// }
+/// ...
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyInputstream : public kodi::addon::CInstanceInputStream
+/// {
+/// public:
+/// CMyInputstream(KODI_HANDLE instance, const std::string& kodiVersion);
+///
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// ...
+/// };
+///
+/// CMyInputstream::CMyInputstream(KODI_HANDLE instance, const std::string& kodiVersion)
+/// : kodi::addon::CInstanceInputStream(instance, kodiVersion)
+/// {
+/// ...
+/// }
+///
+/// ADDON_STATUS CMyInputstream::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_VIDEOCODEC))
+/// {
+/// addonInstance = new CMyVideoCodec(instance, this);
+/// return ADDON_STATUS_OK;
+/// }
+/// return ADDON_STATUS_NOT_IMPLEMENTED;
+/// }
+///
+/// ...
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_INPUTSTREAM))
+/// {
+/// kodi::Log(ADDON_LOG_NOTICE, "Creating my Inputstream");
+/// hdl = new CMyInputstream(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyInputstream` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+///
+class ATTR_DLL_LOCAL CInstanceVideoCodec : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief Video codec class constructor used to support multiple instance
+ /// types
+ ///
+ /// @param[in] instance The instance value given to <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>,
+ /// or by a inputstream instance if them declared as parent.
+ /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to
+ /// allow compatibility to older Kodi versions.
+ ///
+ explicit CInstanceVideoCodec(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceVideoCodec: Creation of multiple together with "
+ "single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief Destructor
+ ///
+ ~CInstanceVideoCodec() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief Open the decoder, returns true on success
+ ///
+ /// Decoders not capable of running multiple instances should return false in case
+ /// there is already a instance open.
+ ///
+ /// @param[in] initData Video codec init data
+ /// @return true if successfully done
+ ///
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata_Help
+ ///
+ virtual bool Open(const kodi::addon::VideoCodecInitdata& initData) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief Reconfigure the decoder, returns true on success
+ ///
+ /// Decoders not capable of running multiple instances may be capable of reconfiguring
+ /// the running instance. If Reconfigure returns false, player will close / open
+ /// the decoder
+ ///
+ /// @param[in] initData Video codec reconfigure data
+ /// @return true if successfully done
+ ///
+ virtual bool Reconfigure(const kodi::addon::VideoCodecInitdata& initData) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief add data, decoder has to consume the entire packet
+ ///
+ /// @param[in] packet Data to process for decode
+ /// @return true if the packet was consumed or if resubmitting it is useless
+ ///
+ virtual bool AddData(const DEMUX_PACKET& packet) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief GetPicture controls decoding.
+ ///
+ /// Player calls it on every cycle it can signal a picture, request a buffer,
+ /// or return none, if nothing applies the data is valid until the next
+ /// GetPicture return @ref VC_PICTURE
+ ///
+ /// @param[in,out] Structure which contains the necessary data
+ /// @return The with @ref VIDEOCODEC_RETVAL return values
+ ///
+ virtual VIDEOCODEC_RETVAL GetPicture(VIDEOCODEC_PICTURE& picture) { return VC_ERROR; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief should return codecs name
+ ///
+ /// @return Codec name
+ ///
+ virtual const char* GetName() { return nullptr; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief Reset the decoder
+ ///
+ virtual void Reset() {}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief AddonToKodi interface
+ */
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief All picture members can be expected to be set correctly except
+ /// decodedData and pts.
+ ///
+ /// GetFrameBuffer has to set decodedData to a valid memory address and return true.
+ ///
+ /// @param[out] picture The buffer, or unmodified if false is returned
+ /// @return In case buffer allocation fails, it return false.
+ ///
+ /// @note If this returns true, buffer must be freed using @ref ReleaseFrameBuffer().
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ bool GetFrameBuffer(VIDEOCODEC_PICTURE& picture)
+ {
+ return m_instanceData->toKodi->get_frame_buffer(m_instanceData->toKodi->kodiInstance, &picture);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ ///
+ /// @ingroup cpp_kodi_addon_videocodec
+ /// @brief Release the with @ref GetFrameBuffer() given framebuffer.
+ ///
+ /// @param[in] handle the on @ref VIDEOCODEC_PICTURE.videoBufferHandle defined buffer handle
+ ///
+ /// @remarks Only called from addon itself
+ ///
+ void ReleaseFrameBuffer(void* buffer)
+ {
+ return m_instanceData->toKodi->release_frame_buffer(m_instanceData->toKodi->kodiInstance,
+ buffer);
+ }
+ //----------------------------------------------------------------------------
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ instance->hdl = this;
+ instance->videocodec->toAddon->open = ADDON_Open;
+ instance->videocodec->toAddon->reconfigure = ADDON_Reconfigure;
+ instance->videocodec->toAddon->add_data = ADDON_AddData;
+ instance->videocodec->toAddon->get_picture = ADDON_GetPicture;
+ instance->videocodec->toAddon->get_name = ADDON_GetName;
+ instance->videocodec->toAddon->reset = ADDON_Reset;
+
+ m_instanceData = instance->videocodec;
+ m_instanceData->toAddon->addonInstance = this;
+ }
+
+ inline static bool ADDON_Open(const AddonInstance_VideoCodec* instance,
+ VIDEOCODEC_INITDATA* initData)
+ {
+ return static_cast<CInstanceVideoCodec*>(instance->toAddon->addonInstance)->Open(initData);
+ }
+
+ inline static bool ADDON_Reconfigure(const AddonInstance_VideoCodec* instance,
+ VIDEOCODEC_INITDATA* initData)
+ {
+ return static_cast<CInstanceVideoCodec*>(instance->toAddon->addonInstance)
+ ->Reconfigure(initData);
+ }
+
+ inline static bool ADDON_AddData(const AddonInstance_VideoCodec* instance,
+ const DEMUX_PACKET* packet)
+ {
+ return static_cast<CInstanceVideoCodec*>(instance->toAddon->addonInstance)->AddData(*packet);
+ }
+
+ inline static VIDEOCODEC_RETVAL ADDON_GetPicture(const AddonInstance_VideoCodec* instance,
+ VIDEOCODEC_PICTURE* picture)
+ {
+ return static_cast<CInstanceVideoCodec*>(instance->toAddon->addonInstance)
+ ->GetPicture(*picture);
+ }
+
+ inline static const char* ADDON_GetName(const AddonInstance_VideoCodec* instance)
+ {
+ return static_cast<CInstanceVideoCodec*>(instance->toAddon->addonInstance)->GetName();
+ }
+
+ inline static void ADDON_Reset(const AddonInstance_VideoCodec* instance)
+ {
+ return static_cast<CInstanceVideoCodec*>(instance->toAddon->addonInstance)->Reset();
+ }
+
+ AddonInstance_VideoCodec* m_instanceData;
+};
+
+} // namespace addon
+} // namespace kodi
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Visualization.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Visualization.h
new file mode 100644
index 0000000..ab35c52
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Visualization.h
@@ -0,0 +1,917 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/addon-instance/visualization.h"
+#include "../gui/renderHelper.h"
+
+#ifdef __cplusplus
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_visualization_Defs_VisualizationTrack class VisualizationTrack
+/// @ingroup cpp_kodi_addon_visualization_Defs
+/// @brief **Info tag data structure**\n
+/// Representation of available information of processed audio file.
+///
+/// This is used to store all the necessary data of audio stream and to have on
+/// e.g. GUI for information.
+///
+/// Called from @ref kodi::addon::CInstanceVisualization::UpdateTrack() with the
+/// information of the currently-playing song.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_visualization_Defs_VisualizationTrack_Help
+///
+///@{
+class VisualizationTrack
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceVisualization;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ VisualizationTrack() = default;
+ VisualizationTrack(const VisualizationTrack& tag) { *this = tag; }
+
+ VisualizationTrack& operator=(const VisualizationTrack& right)
+ {
+ if (&right == this)
+ return *this;
+
+ m_title = right.m_title;
+ m_artist = right.m_artist;
+ m_album = right.m_album;
+ m_albumArtist = right.m_albumArtist;
+ m_genre = right.m_genre;
+ m_comment = right.m_comment;
+ m_lyrics = right.m_lyrics;
+
+ m_trackNumber = right.m_trackNumber;
+ m_discNumber = right.m_discNumber;
+ m_duration = right.m_duration;
+ m_year = right.m_year;
+ m_rating = right.m_rating;
+ return *this;
+ }
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_visualization_Defs_VisualizationTrack_Help Value Help
+ /// @ingroup cpp_kodi_addon_visualization_Defs_VisualizationTrack
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_visualization_Defs_VisualizationTrack :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Title of the current song.** | `std::string` | @ref VisualizationTrack::SetTitle "SetTitle" | @ref VisualizationTrack::GetTitle "GetTitle"
+ /// | **Artist names, as a single string** | `std::string` | @ref VisualizationTrack::SetArtist "SetArtist" | @ref VisualizationTrack::GetArtist "GetArtist"
+ /// | **Album that the current song is from.** | `std::string` | @ref VisualizationTrack::SetAlbum "SetAlbum" | @ref VisualizationTrack::GetAlbum "GetAlbum"
+ /// | **Album artist names, as a single string** | `std::string` | @ref VisualizationTrack::SetAlbumArtist "SetAlbumArtist" | @ref VisualizationTrack::GetAlbumArtist "GetAlbumArtist"
+ /// | **The genre name from the music tag, if present** | `std::string` | @ref VisualizationTrack::SetGenre "SetGenre" | @ref VisualizationTrack::GetGenre "GetGenre"
+ /// | **Duration of the current song, in seconds** | `int` | @ref VisualizationTrack::SetDuration "SetDuration" | @ref VisualizationTrack::GetDuration "GetDuration"
+ /// | **Track number of the current song** | `int` | @ref VisualizationTrack::SetTrack "SetTrack" | @ref VisualizationTrack::GetTrack "GetTrack"
+ /// | **Disc number of the current song stored in the ID tag info** | `int` | @ref VisualizationTrack::SetDisc "SetDisc" | @ref VisualizationTrack::GetDisc "GetDisc"
+ /// | **Year that the current song was released** | `int` | @ref VisualizationTrack::SetYear "SetYear" | @ref VisualizationTrack::GetYear "GetYear"
+ /// | **Lyrics of the current song, if available** | `std::string` | @ref VisualizationTrack::SetLyrics "SetLyrics" | @ref VisualizationTrack::GetLyrics "GetLyrics"
+ /// | **The user-defined rating of the current song** | `int` | @ref VisualizationTrack::SetRating "SetRating" | @ref VisualizationTrack::GetRating "GetRating"
+ /// | **Comment of the current song stored in the ID tag info** | `std::string` | @ref VisualizationTrack::SetComment "SetComment" | @ref VisualizationTrack::GetComment "GetComment"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_visualization_Defs_VisualizationTrack
+ ///@{
+
+ /// @brief Set title of the current song.
+ void SetTitle(const std::string& title) { m_title = title; }
+
+ /// @brief Get title of the current song.
+ const std::string& GetTitle() const { return m_title; }
+
+ /// @brief Set artist names, as a single string-
+ void SetArtist(const std::string& artist) { m_artist = artist; }
+
+ /// @brief Get artist names, as a single string-
+ const std::string& GetArtist() const { return m_artist; }
+
+ /// @brief Set Album that the current song is from.
+ void SetAlbum(const std::string& album) { m_album = album; }
+
+ /// @brief Get Album that the current song is from.
+ const std::string& GetAlbum() const { return m_album; }
+
+ /// @brief Set album artist names, as a single stringalbum artist name
+ void SetAlbumArtist(const std::string& albumArtist) { m_albumArtist = albumArtist; }
+
+ /// @brief Get album artist names, as a single string-
+ const std::string& GetAlbumArtist() const { return m_albumArtist; }
+
+ /// @brief Set genre name from music as string if present.
+ void SetGenre(const std::string& genre) { m_genre = genre; }
+
+ /// @brief Get genre name from music as string if present.
+ const std::string& GetGenre() const { return m_genre; }
+
+ /// @brief Set the duration of music as integer from info.
+ void SetDuration(int duration) { m_duration = duration; }
+
+ /// @brief Get the duration of music as integer from info.
+ int GetDuration() const { return m_duration; }
+
+ /// @brief Set track number (if present) from music info as integer.
+ void SetTrack(int trackNumber) { m_trackNumber = trackNumber; }
+
+ /// @brief Get track number (if present).
+ int GetTrack() const { return m_trackNumber; }
+
+ /// @brief Set disk number (if present) from music info as integer.
+ void SetDisc(int discNumber) { m_discNumber = discNumber; }
+
+ /// @brief Get disk number (if present)
+ int GetDisc() const { return m_discNumber; }
+
+ /// @brief Set year that the current song was released.
+ void SetYear(int year) { m_year = year; }
+
+ /// @brief Get year that the current song was released.
+ int GetYear() const { return m_year; }
+
+ /// @brief Set string from lyrics.
+ void SetLyrics(const std::string& lyrics) { m_lyrics = lyrics; }
+
+ /// @brief Get string from lyrics.
+ const std::string& GetLyrics() const { return m_lyrics; }
+
+ /// @brief Set the user-defined rating of the current song.
+ void SetRating(int rating) { m_rating = rating; }
+
+ /// @brief Get the user-defined rating of the current song.
+ int GetRating() const { return m_rating; }
+
+ /// @brief Set additional information comment (if present).
+ void SetComment(const std::string& comment) { m_comment = comment; }
+
+ /// @brief Get additional information comment (if present).
+ const std::string& GetComment() const { return m_comment; }
+
+ ///@}
+
+private:
+ VisualizationTrack(const KODI_ADDON_VISUALIZATION_TRACK* tag)
+ {
+ if (!tag)
+ return;
+
+ m_title = tag->title ? tag->title : "";
+ m_artist = tag->artist ? tag->artist : "";
+ m_album = tag->album ? tag->album : "";
+ m_albumArtist = tag->albumArtist ? tag->albumArtist : "";
+ m_genre = tag->genre ? tag->genre : "";
+ m_comment = tag->comment ? tag->comment : "";
+ m_lyrics = tag->lyrics ? tag->lyrics : "";
+
+ m_trackNumber = tag->trackNumber;
+ m_discNumber = tag->discNumber;
+ m_duration = tag->duration;
+ m_year = tag->year;
+ m_rating = tag->rating;
+ }
+
+ std::string m_title;
+ std::string m_artist;
+ std::string m_album;
+ std::string m_albumArtist;
+ std::string m_genre;
+ std::string m_comment;
+ std::string m_lyrics;
+
+ int m_trackNumber = 0;
+ int m_discNumber = 0;
+ int m_duration = 0;
+ int m_year = 0;
+ int m_rating = 0;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_visualization_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_visualization
+/// @brief **Visualization add-on instance definition values**\n
+/// All visualization functions associated data structures.
+///
+/// Used to exchange the available options between Kodi and addon.
+///
+
+//==============================================================================
+/// @addtogroup cpp_kodi_addon_visualization
+/// @brief \cpp_class{ kodi::addon::CInstanceVisualization }
+/// **Visualization add-on instance**\n
+/// [Music visualization](https://en.wikipedia.org/wiki/Music_visualization),
+/// or music visualisation, is a feature in Kodi that generates animated
+/// imagery based on a piece of music. The imagery is usually generated and
+/// rendered in real time synchronized to the music.
+///
+/// Visualization techniques range from simple ones (e.g., a simulation of an
+/// oscilloscope display) to elaborate ones, which often include a plurality
+/// of composited effects. The changes in the music's loudness and frequency
+/// spectrum are among the properties used as input to the visualization.
+///
+/// Include the header @ref Visualization.h "#include <kodi/addon-instance/Visualization.h>"
+/// to use this class.
+///
+/// This interface allows the creation of visualizations for Kodi, based upon
+/// **DirectX** or/and **OpenGL** rendering with `C++` code.
+///
+/// Additionally, there are several @ref cpp_kodi_addon_visualization_CB "other functions"
+/// available in which the child class can ask about the current hardware,
+/// including the device, display and several other parts.
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Here's an example on addon.xml:**
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <addon
+/// id="visualization.myspecialnamefor"
+/// version="1.0.0"
+/// name="My special visualization addon"
+/// provider-name="Your Name">
+/// <requires>@ADDON_DEPENDS@</requires>
+/// <extension
+/// point="xbmc.player.musicviz"
+/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
+/// <extension point="xbmc.addon.metadata">
+/// <summary lang="en_GB">My visualization addon addon</summary>
+/// <description lang="en_GB">My visualization addon description</description>
+/// <platform>@PLATFORM@</platform>
+/// </extension>
+/// </addon>
+/// ~~~~~~~~~~~~~
+///
+/// Description to visualization related addon.xml values:
+/// | Name | Description
+/// |:------------------------------|----------------------------------------
+/// | <b>`point`</b> | Addon type specification<br>At all addon types and for this kind always <b>"xbmc.player.musicviz"</b>.
+/// | <b>`library_@PLATFORM@`</b> | Sets the used library name, which is automatically set by cmake at addon build.
+///
+/// --------------------------------------------------------------------------
+///
+/// **Here is an example of the minimum required code to start a visualization:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/Visualization.h>
+///
+/// class CMyVisualization : public kodi::addon::CAddonBase,
+/// public kodi::addon::CInstanceVisualization
+/// {
+/// public:
+/// CMyVisualization();
+///
+/// bool Start(int channels, int samplesPerSec, int bitsPerSample, const std::string& songName) override;
+/// void AudioData(const float* audioData, size_t audioDataLength) override;
+/// void Render() override;
+/// };
+///
+/// CMyVisualization::CMyVisualization()
+/// {
+/// ...
+/// }
+///
+/// bool CMyVisualization::Start(int channels, int samplesPerSec, int bitsPerSample, const std::string& songName)
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// void CMyVisualization::AudioData(const float* audioData, size_t audioDataLength)
+/// {
+/// ...
+/// }
+///
+/// void CMyVisualization::Render()
+/// {
+/// ...
+/// }
+///
+/// ADDONCREATOR(CMyVisualization)
+/// ~~~~~~~~~~~~~
+///
+///
+/// --------------------------------------------------------------------------
+///
+///
+/// **Here is another example where the visualization is used together with
+/// other instance types:**
+///
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/addon-instance/Visualization.h>
+///
+/// class CMyVisualization : public kodi::addon::CInstanceVisualization
+/// {
+/// public:
+/// CMyVisualization(const kodi::addon::IInstanceInfo& instance);
+///
+/// bool Start(int channels, int samplesPerSec, int bitsPerSample, const std::string& songName) override;
+/// void AudioData(const float* audioData, size_t audioDataLength) override;
+/// void Render() override;
+/// };
+///
+/// CMyVisualization::CMyVisualization(const kodi::addon::IInstanceInfo& instance)
+/// : kodi::addon::CInstanceAudioDecoder(instance)
+/// {
+/// ...
+/// }
+///
+/// bool CMyVisualization::Start(int channels, int samplesPerSec, int bitsPerSample, const std::string& songName)
+/// {
+/// ...
+/// return true;
+/// }
+///
+/// void CMyVisualization::AudioData(const float* audioData, size_t audioDataLength)
+/// {
+/// ...
+/// }
+///
+/// void CMyVisualization::Render()
+/// {
+/// ...
+/// }
+///
+///
+/// //----------------------------------------------------------------------
+///
+/// class CMyAddon : public kodi::addon::CAddonBase
+/// {
+/// public:
+/// CMyAddon() = default;
+/// ADDON_STATUS CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+/// KODI_ADDON_INSTANCE_HDL& hdl)
+/// {
+/// if (instance.IsType(ADDON_INSTANCE_VISUALIZATION))
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my visualization");
+/// hdl = new CMyVisualization(instance);
+/// return ADDON_STATUS_OK;
+/// }
+/// else if (...)
+/// {
+/// ...
+/// }
+/// return ADDON_STATUS_UNKNOWN;
+/// }
+///
+/// ADDONCREATOR(CMyAddon)
+/// ~~~~~~~~~~~~~
+///
+/// The destruction of the example class `CMyVisualization` is called from
+/// Kodi's header. Manually deleting the add-on instance is not required.
+///
+class ATTR_DLL_LOCAL CInstanceVisualization : public IAddonInstance
+{
+public:
+ //============================================================================
+ ///
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Visualization class constructor
+ ///
+ /// Used by an add-on that only supports visualizations.
+ ///
+ CInstanceVisualization()
+ : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error(
+ "kodi::addon::CInstanceVisualization: Cannot create multiple instances of add-on.");
+
+ SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
+ CPrivateBase::m_interface->globalSingleInstance = this;
+ }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Visualization class constructor used to support multiple instance
+ /// types.
+ ///
+ /// @param[in] instance The instance value given to
+ /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>.
+ /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to
+ /// allow compatibility to older Kodi versions.
+ ///
+ /// @note Recommended to set <b>`kodiVersion`</b>.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Here's example about the use of this:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// class CMyVisualization : public kodi::addon::CInstanceAudioDecoder
+ /// {
+ /// public:
+ /// CMyVisualization(const kodi::addon::IInstanceInfo& instance)
+ /// : kodi::addon::CInstanceAudioDecoder(instance)
+ /// {
+ /// ...
+ /// }
+ ///
+ /// ...
+ /// };
+ ///
+ /// ADDON_STATUS CMyAddon::CreateInstance(const kodi::addon::IInstanceInfo& instance,
+ /// KODI_ADDON_INSTANCE_HDL& hdl)
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my visualization");
+ /// hdl = new CMyVisualization(instance);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ explicit CInstanceVisualization(const IInstanceInfo& instance) : IAddonInstance(instance)
+ {
+ if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstanceVisualization: Creation of multiple together "
+ "with single instance way is not allowed!");
+
+ SetAddonStruct(instance);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Destructor.
+ ///
+ ~CInstanceVisualization() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Used to notify the visualization that a new song has been started.
+ ///
+ /// @param[in] channels Number of channels in the stream
+ /// @param[in] samplesPerSec Samples per second of stream
+ /// @param[in] bitsPerSample Number of bits in one sample
+ /// @param[in] songName The name of the currently-playing song
+ /// @return true if start successful done
+ ///
+ virtual bool Start(int channels,
+ int samplesPerSec,
+ int bitsPerSample,
+ const std::string& songName)
+ {
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Used to inform the visualization that the rendering control was
+ /// stopped.
+ ///
+ virtual void Stop() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Pass audio data to the visualization.
+ ///
+ /// @param[in] audioData The raw audio data
+ /// @param[in] audioDataLength Length of the audioData array
+ ///
+ virtual void AudioData(const float* audioData, size_t audioDataLength) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Used to inform Kodi that the rendered region is dirty and need an
+ /// update.
+ ///
+ /// @return True if dirty
+ ///
+ virtual bool IsDirty() { return true; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Used to indicate when the add-on should render.
+ ///
+ virtual void Render() {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Used to get the number of buffers from the current visualization.
+ ///
+ /// @return The number of buffers to delay before calling @ref AudioData()
+ ///
+ /// @note If this function is not implemented, it will default to 0.
+ ///
+ virtual int GetSyncDelay() { return 0; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Used to get a list of visualization presets the user can select.
+ /// from
+ ///
+ /// @param[out] presets The vector list containing the names of presets that
+ /// the user can select
+ /// @return Return true if successful, or false if there are no presets to
+ /// choose from
+ ///
+ virtual bool GetPresets(std::vector<std::string>& presets) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Get the index of the current preset.
+ ///
+ /// @return Index number of the current preset
+ ///
+ virtual int GetActivePreset() { return -1; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Check if the add-on is locked to the current preset.
+ ///
+ /// @return True if locked to the current preset
+ ///
+ virtual bool IsLocked() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Load the previous visualization preset.
+ ///
+ /// @return Return true if the previous preset was loaded
+ ///
+ virtual bool PrevPreset() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Load the next visualization preset.
+ ///
+ /// @return Return true if the next preset was loaded
+ ///
+ virtual bool NextPreset() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Load a visualization preset.
+ ///
+ /// This function is called after a new preset is selected.
+ ///
+ /// @param[in] select Preset index to use
+ /// @return Return true if the preset is loaded
+ ///
+ virtual bool LoadPreset(int select) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Switch to a new random preset.
+ ///
+ /// @return Return true if a random preset was loaded
+ ///
+ virtual bool RandomPreset() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Lock the current visualization preset, preventing it from changing.
+ ///
+ /// @param[in] lockUnlock If set to true, the preset should be locked
+ /// @return Return true if the current preset is locked
+ ///
+ virtual bool LockPreset(bool lockUnlock) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Used to increase/decrease the visualization preset rating.
+ ///
+ /// @param[in] plusMinus If set to true the rating is increased, otherwise
+ /// decreased
+ /// @return Return true if the rating is modified
+ ///
+ virtual bool RatePreset(bool plusMinus) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Inform the visualization of the current album art image.
+ ///
+ /// @param[in] albumart Path to the current album art image
+ /// @return Return true if the image is used
+ ///
+ virtual bool UpdateAlbumart(const std::string& albumart) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief Inform the visualization of the current track's tag information.
+ ///
+ /// @param[in] track Visualization track information structure
+ /// @return Return true if the track information is used
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_visualization_Defs_VisualizationTrack_Help
+ ///
+ ///-------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ ///
+ /// #include <kodi/addon-instance/Visualization.h>
+ ///
+ /// class CMyVisualization : public kodi::addon::CInstanceVisualization
+ /// {
+ /// public:
+ /// CMyVisualization(KODI_HANDLE instance, const std::string& version);
+ ///
+ /// ...
+ ///
+ /// private:
+ /// kodi::addon::VisualizationTrack m_runningTrack;
+ /// };
+ ///
+ /// bool CMyVisualization::UpdateTrack(const kodi::addon::VisualizationTrack& track)
+ /// {
+ /// m_runningTrack = track;
+ /// return true;
+ /// }
+ ///
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual bool UpdateTrack(const kodi::addon::VisualizationTrack& track) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_visualization_CB Information functions
+ /// @ingroup cpp_kodi_addon_visualization
+ /// @brief **To get info about the device, display and several other parts**\n
+ /// These are functions to query any values or to transfer them to Kodi.
+ ///
+ ///@{
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization_CB
+ /// @brief To transfer available presets on addon.
+ ///
+ /// Used if @ref GetPresets not possible to use, e.g. where available presets
+ /// are only known during @ref Start call.
+ ///
+ /// @param[in] presets List to store available presets.
+ ///
+ /// @note The function should only be called once, if possible
+ ///
+ inline void TransferPresets(const std::vector<std::string>& presets)
+ {
+ m_instanceData->visualization->toKodi->clear_presets(m_instanceData->info->kodi);
+ for (const auto& it : presets)
+ m_instanceData->visualization->toKodi->transfer_preset(m_instanceData->info->kodi,
+ it.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization_CB
+ /// @brief Device that represents the display adapter.
+ ///
+ /// @return A pointer to the used device with @ref cpp_kodi_Defs_HardwareContext "HardwareContext"
+ ///
+ /// @note This is only available on **DirectX**, It us unused (`nullptr`) on
+ /// **OpenGL**
+ ///
+ ///-------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <d3d11_1.h>
+ /// ..
+ /// // Note: Device() there is used inside addon child class about
+ /// // kodi::addon::CInstanceVisualization
+ /// ID3D11DeviceContext1* context = static_cast<ID3D11DeviceContext1*>(kodi::addon::CInstanceVisualization::Device());
+ /// ..
+ /// ~~~~~~~~~~~~~
+ ///
+ inline kodi::HardwareContext Device() { return m_props.device; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization_CB
+ /// @brief Returns the X position of the rendering window.
+ ///
+ /// @return The X position, in pixels
+ ///
+ inline int X() { return m_props.x; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization_CB
+ /// @brief Returns the Y position of the rendering window.
+ ///
+ /// @return The Y position, in pixels
+ ///
+ inline int Y() { return m_props.y; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization_CB
+ /// @brief Returns the width of the rendering window.
+ ///
+ /// @return The width, in pixels
+ ///
+ inline int Width() { return m_props.width; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization_CB
+ /// @brief Returns the height of the rendering window.
+ ///
+ /// @return The height, in pixels
+ ///
+ inline int Height() { return m_props.height; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_visualization_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_props.pixelRatio; }
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+private:
+ void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
+ {
+ m_instanceData = instance;
+ m_instanceData->hdl = this;
+ m_instanceData->visualization->toAddon->start = ADDON_start;
+ m_instanceData->visualization->toAddon->stop = ADDON_stop;
+ m_instanceData->visualization->toAddon->audio_data = ADDON_audio_data;
+ m_instanceData->visualization->toAddon->is_dirty = ADDON_is_dirty;
+ m_instanceData->visualization->toAddon->render = ADDON_render;
+ m_instanceData->visualization->toAddon->get_sync_delay = ADDON_get_sync_delay;
+ m_instanceData->visualization->toAddon->prev_preset = ADDON_prev_preset;
+ m_instanceData->visualization->toAddon->next_preset = ADDON_next_preset;
+ m_instanceData->visualization->toAddon->load_preset = ADDON_load_preset;
+ m_instanceData->visualization->toAddon->random_preset = ADDON_random_preset;
+ m_instanceData->visualization->toAddon->lock_preset = ADDON_lock_preset;
+ m_instanceData->visualization->toAddon->rate_preset = ADDON_rate_preset;
+ m_instanceData->visualization->toAddon->update_albumart = ADDON_update_albumart;
+ m_instanceData->visualization->toAddon->update_track = ADDON_update_track;
+ m_instanceData->visualization->toAddon->get_presets = ADDON_get_presets;
+ m_instanceData->visualization->toAddon->get_active_preset = ADDON_get_active_preset;
+ m_instanceData->visualization->toAddon->is_locked = ADDON_is_locked;
+
+ m_instanceData->visualization->toKodi->get_properties(instance->info->kodi, &m_props);
+ }
+
+ inline static bool ADDON_start(const KODI_ADDON_VISUALIZATION_HDL hdl,
+ int channels,
+ int samplesPerSec,
+ int bitsPerSample,
+ const char* songName)
+ {
+ CInstanceVisualization* thisClass = static_cast<CInstanceVisualization*>(hdl);
+ thisClass->m_renderHelper = kodi::gui::GetRenderHelper();
+ return thisClass->Start(channels, samplesPerSec, bitsPerSample, songName);
+ }
+
+ inline static void ADDON_stop(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ CInstanceVisualization* thisClass = static_cast<CInstanceVisualization*>(hdl);
+ thisClass->Stop();
+ thisClass->m_renderHelper = nullptr;
+ }
+
+ inline static void ADDON_audio_data(const KODI_ADDON_VISUALIZATION_HDL hdl,
+ const float* audioData,
+ size_t audioDataLength)
+ {
+ static_cast<CInstanceVisualization*>(hdl)->AudioData(audioData, audioDataLength);
+ }
+
+ inline static bool ADDON_is_dirty(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->IsDirty();
+ }
+
+ inline static void ADDON_render(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ CInstanceVisualization* thisClass = static_cast<CInstanceVisualization*>(hdl);
+ if (!thisClass->m_renderHelper)
+ return;
+ thisClass->m_renderHelper->Begin();
+ thisClass->Render();
+ thisClass->m_renderHelper->End();
+ }
+
+ inline static int ADDON_get_sync_delay(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->GetSyncDelay();
+ }
+
+ inline static unsigned int ADDON_get_presets(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ CInstanceVisualization* thisClass = static_cast<CInstanceVisualization*>(hdl);
+ std::vector<std::string> presets;
+ if (thisClass->GetPresets(presets))
+ {
+ for (const auto& it : presets)
+ thisClass->m_instanceData->visualization->toKodi->transfer_preset(
+ thisClass->m_instanceData->info->kodi, it.c_str());
+ }
+
+ return static_cast<unsigned int>(presets.size());
+ }
+
+ inline static int ADDON_get_active_preset(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->GetActivePreset();
+ }
+
+ inline static bool ADDON_prev_preset(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->PrevPreset();
+ }
+
+ inline static bool ADDON_next_preset(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->NextPreset();
+ }
+
+ inline static bool ADDON_load_preset(const KODI_ADDON_VISUALIZATION_HDL hdl, int select)
+
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->LoadPreset(select);
+ }
+
+ inline static bool ADDON_random_preset(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->RandomPreset();
+ }
+
+ inline static bool ADDON_lock_preset(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ CInstanceVisualization* thisClass = static_cast<CInstanceVisualization*>(hdl);
+ thisClass->m_presetLockedByUser = !thisClass->m_presetLockedByUser;
+ return thisClass->LockPreset(thisClass->m_presetLockedByUser);
+ }
+
+ inline static bool ADDON_rate_preset(const KODI_ADDON_VISUALIZATION_HDL hdl, bool plus_minus)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->RatePreset(plus_minus);
+ }
+
+ inline static bool ADDON_is_locked(const KODI_ADDON_VISUALIZATION_HDL hdl)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->IsLocked();
+ }
+
+ inline static bool ADDON_update_albumart(const KODI_ADDON_VISUALIZATION_HDL hdl,
+ const char* albumart)
+ {
+ return static_cast<CInstanceVisualization*>(hdl)->UpdateAlbumart(albumart);
+ }
+
+ inline static bool ADDON_update_track(const KODI_ADDON_VISUALIZATION_HDL hdl,
+ const KODI_ADDON_VISUALIZATION_TRACK* track)
+ {
+ VisualizationTrack cppTrack(track);
+ return static_cast<CInstanceVisualization*>(hdl)->UpdateTrack(cppTrack);
+ }
+
+ std::shared_ptr<kodi::gui::IRenderHelper> m_renderHelper;
+ bool m_presetLockedByUser = false;
+ KODI_ADDON_INSTANCE_STRUCT* m_instanceData{nullptr};
+ KODI_ADDON_VISUALIZATION_PROPS m_props = {};
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/CMakeLists.txt
new file mode 100644
index 0000000..ebbeeb7
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ DemuxPacket.h
+ StreamCodec.h
+ StreamConstants.h
+ StreamCrypto.h
+ TimingConstants.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_addon-instance_inputstream)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/DemuxPacket.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/DemuxPacket.h
new file mode 100644
index 0000000..f965b9f
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/DemuxPacket.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#include "TimingConstants.h"
+#include "../../c-api/addon-instance/inputstream/demux_packet.h"
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCodec.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCodec.h
new file mode 100644
index 0000000..e80e2ca
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCodec.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#include "../../c-api/addon-instance/inputstream/stream_codec.h"
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamConstants.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamConstants.h
new file mode 100644
index 0000000..200631b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamConstants.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#include "../../c-api/addon-instance/inputstream/stream_constants.h"
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCrypto.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCrypto.h
new file mode 100644
index 0000000..8e04ae3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/StreamCrypto.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#include "../../c-api/addon-instance/inputstream/stream_crypto.h"
+#include "../../AddonBase.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+class CInstanceInputStream;
+class InputstreamInfo;
+class VideoCodecInitdata;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_inputstream_Defs_StreamEncryption_StreamCryptoSession class StreamCryptoSession
+/// @ingroup cpp_kodi_addon_inputstream_Defs_StreamEncryption
+/// @brief **Data to manage stream cryptography**\n
+/// This class structure manages any encryption values required in order to have
+/// them available in their stream processing.
+///
+/// Used on inputstream by @ref kodi::addon::InputstreamInfo::SetCryptoSession /
+/// @ref kodi::addon::InputstreamInfo::GetCryptoSession and are given to the
+/// used video codec to decrypt related data.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_inputstream_Defs_Info_StreamCryptoSession_Help
+///
+///@{
+class ATTR_DLL_LOCAL StreamCryptoSession
+ : public CStructHdl<StreamCryptoSession, STREAM_CRYPTO_SESSION>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceInputStream;
+ friend class InputstreamInfo;
+ friend class VideoCodecInitdata;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ StreamCryptoSession() { memset(m_cStructure, 0, sizeof(STREAM_CRYPTO_SESSION)); }
+ StreamCryptoSession(const StreamCryptoSession& session) : CStructHdl(session) {}
+ StreamCryptoSession& operator=(const StreamCryptoSession&) = default;
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Info_StreamCryptoSession_Help Value Help
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Info_StreamCryptoSession
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_inputstream_Defs_Info_StreamCryptoSession :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Keysystem for encrypted media** | @ref STREAM_CRYPTO_KEY_SYSTEM | @ref StreamCryptoSession::SetKeySystem "SetKeySystem" | @ref StreamCryptoSession::GetKeySystem "GetKeySystem"
+ /// | **Flags for special conditions** | `uint8_t` | @ref StreamCryptoSession::SetFlags "SetFlags" | @ref StreamCryptoSession::GetFlags "GetFlags"
+ /// | **Crypto session key id** | `std::string` | @ref StreamCryptoSession::SetSessionId "SetSessionId" | @ref StreamCryptoSession::GetSessionId "GetSessionId"
+
+ /// @brief To set keysystem for encrypted media, @ref STREAM_CRYPTO_KEY_SYSTEM_NONE for
+ /// unencrypted media.
+ ///
+ /// See @ref STREAM_CRYPTO_KEY_SYSTEM for available options.
+ void SetKeySystem(STREAM_CRYPTO_KEY_SYSTEM keySystem) { m_cStructure->keySystem = keySystem; }
+
+ /// @brief Get keysystem for encrypted media.
+ STREAM_CRYPTO_KEY_SYSTEM GetKeySystem() const { return m_cStructure->keySystem; }
+
+ /// @brief Set bit flags to use special conditions, see @ref STREAM_CRYPTO_FLAGS
+ /// for available flags.
+ void SetFlags(uint8_t flags) { m_cStructure->flags = flags; }
+
+ /// @brief Get flags for special conditions.
+ uint8_t GetFlags() const { return m_cStructure->flags; }
+
+ /// @brief To set the crypto session key identifier.
+ void SetSessionId(const std::string& sessionId)
+ {
+ strncpy(m_cStructure->sessionId, sessionId.c_str(), sizeof(m_cStructure->sessionId) - 1);
+ }
+
+ /// @brief To get the crypto session key identifier.
+ std::string GetSessionId() const { return m_cStructure->sessionId; }
+
+private:
+ StreamCryptoSession(const STREAM_CRYPTO_SESSION* session) : CStructHdl(session) {}
+ StreamCryptoSession(STREAM_CRYPTO_SESSION* session) : CStructHdl(session) {}
+};
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/TimingConstants.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/TimingConstants.h
new file mode 100644
index 0000000..22f8952
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/inputstream/TimingConstants.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#include "../../c-api/addon-instance/inputstream/timing_constants.h"
+
+#ifdef __cplusplus
+
+// Unset the on timing_constants.h given defines
+#undef STREAM_TIME_TO_MSEC
+#undef STREAM_SEC_TO_TIME
+#undef STREAM_MSEC_TO_TIME
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_TimingConstants
+/// @brief Converts a stream time to milliseconds as an integer value.
+///
+/// @param[in] x Stream time
+/// @return Milliseconds
+///
+/// @note Within "C" code this is used as `#define`.
+///
+constexpr int STREAM_TIME_TO_MSEC(double x)
+{
+ return static_cast<int>(x * 1000 / STREAM_TIME_BASE);
+}
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_TimingConstants
+/// @brief Converts a time in seconds to the used stream time format.
+///
+/// @param[in] x Seconds
+/// @return Stream time
+///
+/// @note Within "C" code this is used as `#define`.
+///
+constexpr double STREAM_SEC_TO_TIME(double x)
+{
+ return x * STREAM_TIME_BASE;
+}
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_TimingConstants
+/// @brief Converts a time in milliseconds to the used stream time format.
+///
+/// @param[in] x Milliseconds
+/// @return Stream time
+///
+/// @note Within "C" code this is used as `#define`.
+///
+constexpr double STREAM_MSEC_TO_TIME(double x)
+{
+ return x * STREAM_TIME_BASE / 1000;
+}
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/CMakeLists.txt
new file mode 100644
index 0000000..135358e
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ PeripheralUtils.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_addon-instance_peripheral)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h
new file mode 100644
index 0000000..bedd7cb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h
@@ -0,0 +1,1277 @@
+/*
+ * Copyright (C) 2014-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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/peripheral.h"
+
+#ifdef __cplusplus
+
+#include <array> // Requires c++11
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#define PERIPHERAL_SAFE_DELETE(x) \
+ do \
+ { \
+ delete (x); \
+ (x) = NULL; \
+ } while (0)
+#define PERIPHERAL_SAFE_DELETE_ARRAY(x) \
+ do \
+ { \
+ delete[](x); \
+ (x) = NULL; \
+ } while (0)
+
+namespace kodi
+{
+namespace addon
+{
+
+class CInstancePeripheral;
+
+/*!
+ * Utility class to manipulate arrays of peripheral types.
+ */
+template<class THE_CLASS, typename THE_STRUCT>
+class PeripheralVector
+{
+public:
+ static void ToStructs(const std::vector<THE_CLASS>& vecObjects, THE_STRUCT** pStructs)
+ {
+ if (!pStructs)
+ return;
+
+ if (vecObjects.empty())
+ {
+ *pStructs = NULL;
+ }
+ else
+ {
+ (*pStructs) = new THE_STRUCT[vecObjects.size()];
+ for (unsigned int i = 0; i < vecObjects.size(); i++)
+ vecObjects.at(i).ToStruct((*pStructs)[i]);
+ }
+ }
+
+ static void ToStructs(const std::vector<THE_CLASS*>& vecObjects, THE_STRUCT** pStructs)
+ {
+ if (!pStructs)
+ return;
+
+ if (vecObjects.empty())
+ {
+ *pStructs = NULL;
+ }
+ else
+ {
+ *pStructs = new THE_STRUCT[vecObjects.size()];
+ for (unsigned int i = 0; i < vecObjects.size(); i++)
+ vecObjects.at(i)->ToStruct((*pStructs)[i]);
+ }
+ }
+
+ static void ToStructs(const std::vector<std::shared_ptr<THE_CLASS>>& vecObjects,
+ THE_STRUCT** pStructs)
+ {
+ if (!pStructs)
+ return;
+
+ if (vecObjects.empty())
+ {
+ *pStructs = NULL;
+ }
+ else
+ {
+ *pStructs = new THE_STRUCT[vecObjects.size()];
+ for (unsigned int i = 0; i < vecObjects.size(); i++)
+ vecObjects.at(i)->ToStruct((*pStructs)[i]);
+ }
+ }
+
+ static void FreeStructs(unsigned int structCount, THE_STRUCT* structs)
+ {
+ if (structs)
+ {
+ for (unsigned int i = 0; i < structCount; i++)
+ THE_CLASS::FreeStruct(structs[i]);
+ }
+ PERIPHERAL_SAFE_DELETE_ARRAY(structs);
+ }
+};
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities class PeripheralCapabilities
+/// @ingroup cpp_kodi_addon_peripheral_Defs_General
+/// @brief **%Peripheral add-on capabilities**\n
+/// This class is needed to tell Kodi which options are supported on the addon.
+///
+/// If a capability is set to **true**, then the corresponding methods from
+/// @ref cpp_kodi_addon_peripheral "kodi::addon::CInstancePeripheral" need to be
+/// implemented.
+///
+/// As default them all set to **false**.
+///
+/// Used on @ref kodi::addon::CInstancePeripheral::GetCapabilities().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities_Help
+///
+///@{
+class PeripheralCapabilities : public CStructHdl<PeripheralCapabilities, PERIPHERAL_CAPABILITIES>
+{
+ /*! \cond PRIVATE */
+ friend class CInstancePeripheral;
+ /*! \endcond */
+
+public:
+ /*! \cond PRIVATE */
+ PeripheralCapabilities()
+ {
+ m_cStructure->provides_joysticks = false;
+ m_cStructure->provides_joystick_rumble = false;
+ m_cStructure->provides_joystick_power_off = false;
+ m_cStructure->provides_buttonmaps = false;
+ }
+
+ PeripheralCapabilities(const PeripheralCapabilities& data) : CStructHdl(data) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities_Help Value Help
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Provides joysticks** | `boolean` | @ref PeripheralCapabilities::SetProvidesJoysticks "SetProvidesJoysticks" | @ref PeripheralCapabilities::GetProvidesJoysticks "GetProvidesJoysticks"
+ /// | **Provides joystick rumble** | `boolean` | @ref PeripheralCapabilities::SetProvidesJoystickRumble "SetProvidesJoystickRumble" | @ref PeripheralCapabilities::GetProvidesJoystickRumble "GetProvidesJoystickRumble"
+ /// | **Provides joystick power off** | `boolean` | @ref PeripheralCapabilities::SetProvidesJoystickPowerOff "SetProvidesJoystickPowerOff" | @ref PeripheralCapabilities::GetProvidesJoystickPowerOff "GetProvidesJoystickPowerOff"
+ /// | **Provides button maps** | `boolean` | @ref PeripheralCapabilities::SetProvidesButtonmaps "SetProvidesButtonmaps" | @ref PeripheralCapabilities::GetProvidesButtonmaps "GetProvidesButtonmaps"
+
+ /// @addtogroup cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities
+ ///@{
+
+ /// @brief Set true if the add-on provides joysticks.
+ void SetProvidesJoysticks(bool providesJoysticks)
+ {
+ m_cStructure->provides_joysticks = providesJoysticks;
+ }
+
+ /// @brief To get with @ref SetProvidesJoysticks changed values.
+ bool GetProvidesJoysticks() const { return m_cStructure->provides_joysticks; }
+
+ /// @brief Set true if the add-on provides joystick rumble.
+ void SetProvidesJoystickRumble(bool providesJoystickRumble)
+ {
+ m_cStructure->provides_joystick_rumble = providesJoystickRumble;
+ }
+
+ /// @brief To get with @ref SetProvidesJoystickRumble changed values.
+ bool GetProvidesJoystickRumble() const { return m_cStructure->provides_joystick_rumble; }
+
+ /// @brief Set true if the add-on provides power off about joystick.
+ void SetProvidesJoystickPowerOff(bool providesJoystickPowerOff)
+ {
+ m_cStructure->provides_joystick_power_off = providesJoystickPowerOff;
+ }
+
+ /// @brief To get with @ref SetProvidesJoystickPowerOff changed values.
+ bool GetProvidesJoystickPowerOff() const { return m_cStructure->provides_joystick_power_off; }
+
+ /// @brief Set true if the add-on provides button maps.
+ void SetProvidesButtonmaps(bool providesButtonmaps)
+ {
+ m_cStructure->provides_buttonmaps = providesButtonmaps;
+ }
+
+ /// @brief To get with @ref SetProvidesButtonmaps changed values.
+ bool GetProvidesButtonmaps() const { return m_cStructure->provides_buttonmaps; }
+
+ ///@}
+
+private:
+ PeripheralCapabilities(const PERIPHERAL_CAPABILITIES* data) : CStructHdl(data) {}
+ PeripheralCapabilities(PERIPHERAL_CAPABILITIES* data) : CStructHdl(data) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral class Peripheral
+/// @ingroup cpp_kodi_addon_peripheral_Defs_Peripheral
+/// @brief **Wrapper class providing peripheral information**\n
+/// Classes can extend %Peripheral to inherit peripheral properties.
+///
+/// Used on @ref kodi::addon::CInstancePeripheral::PerformDeviceScan().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral_Help
+///
+///@{
+class Peripheral
+{
+public:
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral_Help Value Help
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **%Peripheral type** | @ref PERIPHERAL_TYPE | @ref Peripheral::SetType "SetType" | @ref Peripheral::Type "Type"
+ /// | **%Peripheral name** | `const std::string&` | @ref Peripheral::SetName "SetName" | @ref Peripheral::Name "Name"
+ /// | **%Peripheral vendor id** | `uint16_t` | @ref Peripheral::SetVendorID "SetVendorID" | @ref Peripheral::VendorID "VendorID"
+ /// | **%Peripheral product id** | `uint16_t` | @ref Peripheral::SetProductID "SetProductID" | @ref Peripheral::ProductID "ProductID"
+ /// | **%Peripheral index** | `unsigned int` | @ref Peripheral::SetIndex "SetIndex" | @ref Peripheral::Index "Index"
+ ///
+ /// Further are following included:
+ /// - @ref Peripheral::Peripheral "Peripheral(PERIPHERAL_TYPE type = PERIPHERAL_TYPE_UNKNOWN, const std::string& strName = \"\")": Class constructor.
+ /// - @ref Peripheral::IsVidPidKnown "IsVidPidKnown()": To check VID and PID are known.
+ ///
+
+ /// @addtogroup cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral
+ ///@{
+
+ /// @brief Constructor.
+ ///
+ /// @param[in] type [optional] Peripheral type, or @ref PERIPHERAL_TYPE_UNKNOWN
+ /// as default
+ /// @param[in] strName [optional] Name of related peripheral
+ Peripheral(PERIPHERAL_TYPE type = PERIPHERAL_TYPE_UNKNOWN, const std::string& strName = "")
+ : m_type(type), m_strName(strName)
+ {
+ }
+
+ /// @brief Destructor.
+ virtual ~Peripheral(void) = default;
+
+ /// @brief Get peripheral type.
+ ///
+ /// @return Type defined with @ref PERIPHERAL_TYPE
+ PERIPHERAL_TYPE Type(void) const { return m_type; }
+
+ /// @brief Get peripheral name.
+ ///
+ /// @return Name string of peripheral
+ const std::string& Name(void) const { return m_strName; }
+
+ /// @brief Get peripheral vendor id.
+ ///
+ /// @return Vendor id
+ uint16_t VendorID(void) const { return m_vendorId; }
+
+ /// @brief Get peripheral product id.
+ ///
+ /// @return Product id
+ uint16_t ProductID(void) const { return m_productId; }
+
+ /// @brief Get peripheral index identifier.
+ ///
+ /// @return Index number
+ unsigned int Index(void) const { return m_index; }
+
+ /// @brief Check VID and PID are known.
+ ///
+ /// @return true if VID and PID are not 0
+ ///
+ /// @note Derived property: VID and PID are `0x0000` if unknown
+ bool IsVidPidKnown(void) const { return m_vendorId != 0 || m_productId != 0; }
+
+ /// @brief Set peripheral type.
+ ///
+ /// @param[in] type Type to set
+ void SetType(PERIPHERAL_TYPE type) { m_type = type; }
+
+ /// @brief Set peripheral name.
+ ///
+ /// @param[in] strName Name to set
+ void SetName(const std::string& strName) { m_strName = strName; }
+
+ /// @brief Set peripheral vendor id.
+ ///
+ /// @param[in] vendorId Type to set
+ void SetVendorID(uint16_t vendorId) { m_vendorId = vendorId; }
+
+ /// @brief Set peripheral product identifier.
+ ///
+ /// @param[in] productId Type to set
+ void SetProductID(uint16_t productId) { m_productId = productId; }
+
+ /// @brief Set peripheral index.
+ ///
+ /// @param[in] index Type to set
+ void SetIndex(unsigned int index) { m_index = index; }
+
+ ///@}
+
+ explicit Peripheral(const PERIPHERAL_INFO& info)
+ : m_type(info.type),
+ m_strName(info.name ? info.name : ""),
+ m_vendorId(info.vendor_id),
+ m_productId(info.product_id),
+ m_index(info.index)
+ {
+ }
+
+ void ToStruct(PERIPHERAL_INFO& info) const
+ {
+ info.type = m_type;
+ info.name = new char[m_strName.size() + 1];
+ info.vendor_id = m_vendorId;
+ info.product_id = m_productId;
+ info.index = m_index;
+
+ std::strcpy(info.name, m_strName.c_str());
+ }
+
+ static void FreeStruct(PERIPHERAL_INFO& info) { PERIPHERAL_SAFE_DELETE_ARRAY(info.name); }
+
+private:
+ PERIPHERAL_TYPE m_type;
+ std::string m_strName;
+ uint16_t m_vendorId = 0;
+ uint16_t m_productId = 0;
+ unsigned int m_index = 0;
+};
+///@}
+//------------------------------------------------------------------------------
+
+typedef PeripheralVector<Peripheral, PERIPHERAL_INFO> Peripherals;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent class PeripheralEvent
+/// @ingroup cpp_kodi_addon_peripheral_Defs_Peripheral
+/// @brief **Wrapper class for %peripheral events**\n
+/// To handle data of change events between add-on and Kodi.
+///
+/// Used on @ref kodi::addon::CInstancePeripheral::GetEvents() and
+/// @ref kodi::addon::CInstancePeripheral::SendEvent().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent_Help
+///
+///@{
+class PeripheralEvent
+{
+public:
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent_Help Value Help
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **%Peripheral event type** | @ref PERIPHERAL_EVENT_TYPE | @ref PeripheralEvent::SetType "SetType" | @ref PeripheralEvent::Type "Type"
+ /// | **%Peripheral index** | `unsigned int` | @ref PeripheralEvent::SetPeripheralIndex "SetPeripheralIndex" | @ref PeripheralEvent::PeripheralIndex "PeripheralIndex"
+ /// | **%Peripheral event driver index** | `unsigned int` | @ref PeripheralEvent::SetDriverIndex "SetDriverIndex" | @ref PeripheralEvent::DriverIndex "DriverIndex"
+ /// | **%Peripheral event button state** | @ref JOYSTICK_STATE_BUTTON | @ref PeripheralEvent::SetButtonState "SetButtonState" | @ref PeripheralEvent::ButtonState "ButtonState"
+ /// | **%Peripheral event hat state** | @ref JOYSTICK_STATE_HAT | @ref PeripheralEvent::SetHatState "SetHatState" | @ref PeripheralEvent::HatState "HatState"
+ /// | **%Peripheral event axis state** | @ref JOYSTICK_STATE_AXIS (`float`) | @ref PeripheralEvent::SetAxisState "SetAxisState" | @ref PeripheralEvent::AxisState "AxisState"
+ /// | **%Peripheral event motor state** | @ref JOYSTICK_STATE_MOTOR (`float`) | @ref PeripheralEvent::SetMotorState "SetMotorState" | @ref PeripheralEvent::MotorState "MotorState"
+ ///
+ /// Further are several class constructors with values included.
+
+ /// @addtogroup cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent
+ ///@{
+
+ /// @brief Constructor.
+ PeripheralEvent() = default;
+
+ /// @brief Constructor.
+ ///
+ /// @param[in] peripheralIndex %Peripheral index
+ /// @param[in] buttonIndex Button index
+ /// @param[in] state Joystick state button
+ PeripheralEvent(unsigned int peripheralIndex,
+ unsigned int buttonIndex,
+ JOYSTICK_STATE_BUTTON state)
+ : m_type(PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON),
+ m_peripheralIndex(peripheralIndex),
+ m_driverIndex(buttonIndex),
+ m_buttonState(state)
+ {
+ }
+
+ /// @brief Constructor.
+ ///
+ /// @param[in] peripheralIndex %Peripheral index
+ /// @param[in] hatIndex Hat index
+ /// @param[in] state Joystick state hat
+ PeripheralEvent(unsigned int peripheralIndex, unsigned int hatIndex, JOYSTICK_STATE_HAT state)
+ : m_type(PERIPHERAL_EVENT_TYPE_DRIVER_HAT),
+ m_peripheralIndex(peripheralIndex),
+ m_driverIndex(hatIndex),
+ m_hatState(state)
+ {
+ }
+
+ /// @brief Constructor.
+ ///
+ /// @param[in] peripheralIndex %Peripheral index
+ /// @param[in] axisIndex Axis index
+ /// @param[in] state Joystick state axis
+ PeripheralEvent(unsigned int peripheralIndex, unsigned int axisIndex, JOYSTICK_STATE_AXIS state)
+ : m_type(PERIPHERAL_EVENT_TYPE_DRIVER_AXIS),
+ m_peripheralIndex(peripheralIndex),
+ m_driverIndex(axisIndex),
+ m_axisState(state)
+ {
+ }
+
+ /// @brief Get type of event.
+ ///
+ /// @return Type defined with @ref PERIPHERAL_EVENT_TYPE
+ PERIPHERAL_EVENT_TYPE Type(void) const { return m_type; }
+
+ /// @brief Get peripheral index.
+ ///
+ /// @return %Peripheral index number
+ unsigned int PeripheralIndex(void) const { return m_peripheralIndex; }
+
+ /// @brief Get driver index.
+ ///
+ /// @return Driver index number
+ unsigned int DriverIndex(void) const { return m_driverIndex; }
+
+ /// @brief Get button state.
+ ///
+ /// @return Button state as @ref JOYSTICK_STATE_BUTTON
+ JOYSTICK_STATE_BUTTON ButtonState(void) const { return m_buttonState; }
+
+ /// @brief Get hat state.
+ ///
+ /// @return Hat state
+ JOYSTICK_STATE_HAT HatState(void) const { return m_hatState; }
+
+ /// @brief Get axis state.
+ ///
+ /// @return Axis state
+ JOYSTICK_STATE_AXIS AxisState(void) const { return m_axisState; }
+
+ /// @brief Get motor state.
+ ///
+ /// @return Motor state
+ JOYSTICK_STATE_MOTOR MotorState(void) const { return m_motorState; }
+
+ /// @brief Set type of event.
+ ///
+ /// @param[in] type Type defined with @ref PERIPHERAL_EVENT_TYPE
+ void SetType(PERIPHERAL_EVENT_TYPE type) { m_type = type; }
+
+ /// @brief Set peripheral index.
+ ///
+ /// @param[in] index %Peripheral index number
+ void SetPeripheralIndex(unsigned int index) { m_peripheralIndex = index; }
+
+ /// @brief Set driver index.
+ ///
+ /// @param[in] index Driver index number
+ void SetDriverIndex(unsigned int index) { m_driverIndex = index; }
+
+ /// @brief Set button state.
+ ///
+ /// @param[in] state Button state as @ref JOYSTICK_STATE_BUTTON
+ void SetButtonState(JOYSTICK_STATE_BUTTON state) { m_buttonState = state; }
+
+ /// @brief Set hat state.
+ ///
+ /// @param[in] state Hat state as @ref JOYSTICK_STATE_HAT (float)
+ void SetHatState(JOYSTICK_STATE_HAT state) { m_hatState = state; }
+
+ /// @brief Set axis state.
+ ///
+ /// @param[in] state Axis state as @ref JOYSTICK_STATE_AXIS (float)
+ void SetAxisState(JOYSTICK_STATE_AXIS state) { m_axisState = state; }
+
+ /// @brief Set motor state.
+ ///
+ /// @param[in] state Motor state as @ref JOYSTICK_STATE_MOTOR (float)
+ void SetMotorState(JOYSTICK_STATE_MOTOR state) { m_motorState = state; }
+
+ ///@}
+
+ explicit PeripheralEvent(const PERIPHERAL_EVENT& event)
+ : m_type(event.type),
+ m_peripheralIndex(event.peripheral_index),
+ m_driverIndex(event.driver_index),
+ m_buttonState(event.driver_button_state),
+ m_hatState(event.driver_hat_state),
+ m_axisState(event.driver_axis_state),
+ m_motorState(event.motor_state)
+ {
+ }
+
+ void ToStruct(PERIPHERAL_EVENT& event) const
+ {
+ event.type = m_type;
+ event.peripheral_index = m_peripheralIndex;
+ event.driver_index = m_driverIndex;
+ event.driver_button_state = m_buttonState;
+ event.driver_hat_state = m_hatState;
+ event.driver_axis_state = m_axisState;
+ event.motor_state = m_motorState;
+ }
+
+ static void FreeStruct(PERIPHERAL_EVENT& event) { (void)event; }
+
+private:
+ PERIPHERAL_EVENT_TYPE m_type = PERIPHERAL_EVENT_TYPE_NONE;
+ unsigned int m_peripheralIndex = 0;
+ unsigned int m_driverIndex = 0;
+ JOYSTICK_STATE_BUTTON m_buttonState = JOYSTICK_STATE_BUTTON_UNPRESSED;
+ JOYSTICK_STATE_HAT m_hatState = JOYSTICK_STATE_HAT_UNPRESSED;
+ JOYSTICK_STATE_AXIS m_axisState = 0.0f;
+ JOYSTICK_STATE_MOTOR m_motorState = 0.0f;
+};
+///@}
+//------------------------------------------------------------------------------
+
+typedef PeripheralVector<PeripheralEvent, PERIPHERAL_EVENT> PeripheralEvents;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_Joystick class Joystick
+/// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+/// @brief **Wrapper class providing additional joystick information**\n
+/// This is a child class to expand another class with necessary joystick data.
+///
+/// For data not provided by @ref cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral.
+///
+/// Used on:
+/// - @ref kodi::addon::CInstancePeripheral::GetJoystickInfo()
+/// - @ref kodi::addon::CInstancePeripheral::GetFeatures().
+/// - @ref kodi::addon::CInstancePeripheral::MapFeatures().
+/// - @ref kodi::addon::CInstancePeripheral::GetIgnoredPrimitives().
+/// - @ref kodi::addon::CInstancePeripheral::SetIgnoredPrimitives().
+/// - @ref kodi::addon::CInstancePeripheral::SaveButtonMap().
+/// - @ref kodi::addon::CInstancePeripheral::RevertButtonMap().
+/// - @ref kodi::addon::CInstancePeripheral::ResetButtonMap().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_peripheral_Defs_Joystick_Joystick_Help
+///
+///@{
+class Joystick : public Peripheral
+{
+public:
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_Joystick_Help Value Help
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick_Joystick
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_peripheral_Defs_Joystick_Joystick :</b>
+ /// | Name | Type | Class | Set call | Get call
+ /// |------|------|-------|----------|----------
+ /// | **%Joystick provider** | `const std::string&` | @ref Joystick | @ref Joystick::SetProvider "SetProvider" | @ref Joystick::Provider "Provider"
+ /// | **%Joystick requested port** | `int` | @ref Joystick | @ref Joystick::SetRequestedPort "SetRequestedPort" | @ref Joystick::RequestedPort "RequestedPort"
+ /// | **%Joystick button count** | `unsigned int` | @ref Joystick | @ref Joystick::SetButtonCount "SetButtonCount" | @ref Joystick::ButtonCount "ButtonCount"
+ /// | **%Joystick hat count** | `unsigned int` | @ref Joystick | @ref Joystick::SetHatCount "SetHatCount" | @ref Joystick::HatCount "HatCount"
+ /// | **%Joystick axis count** | `unsigned int` | @ref Joystick | @ref Joystick::SetAxisCount "SetAxisCount" | @ref Joystick::AxisCount "AxisCount"
+ /// | **%Joystick motor count** | `unsigned int` | @ref Joystick | @ref Joystick::SetMotorCount "SetMotorCount" | @ref Joystick::MotorCount "MotorCount"
+ /// | **%Joystick support power off** | `bool` | @ref Joystick | @ref Joystick::SetSupportsPowerOff "SetSupportsPowerOff" | @ref Joystick::SupportsPowerOff "SupportsPowerOff"
+ /// | **%Peripheral type** | @ref PERIPHERAL_TYPE | @ref Peripheral | @ref Peripheral::SetType "SetType" | @ref Peripheral::Type "Type"
+ /// | **%Peripheral name** | `const std::string&` | @ref Peripheral | @ref Peripheral::SetName "SetName" | @ref Peripheral::Name "Name"
+ /// | **%Peripheral vendor id** | `uint16_t` | @ref Peripheral | @ref Peripheral::SetVendorID "SetVendorID" | @ref Peripheral::VendorID "VendorID"
+ /// | **%Peripheral product id** | `uint16_t` | @ref Peripheral | @ref Peripheral::SetProductID "SetProductID" | @ref Peripheral::ProductID "ProductID"
+ /// | **%Peripheral index** | `unsigned int` | @ref Peripheral | @ref Peripheral::SetIndex "SetIndex" | @ref Peripheral::Index "Index"
+ ///
+ /// Further are following included:
+ /// - @ref Joystick::Joystick "Joystick(const std::string& provider = \"\", const std::string& strName = \"\")"
+ /// - @ref Joystick::operator= "Joystick& operator=(const Joystick& rhs)"
+ /// - @ref Peripheral::IsVidPidKnown "IsVidPidKnown()": To check VID and PID are known.
+ ///
+
+ /// @addtogroup cpp_kodi_addon_peripheral_Defs_Joystick_Joystick
+ ///@{
+
+ /// @brief Constructor.
+ ///
+ /// @param[in] provider [optional] Provide name
+ /// @param[in] strName [optional] Name of related joystick
+ Joystick(const std::string& provider = "", const std::string& strName = "")
+ : Peripheral(PERIPHERAL_TYPE_JOYSTICK, strName),
+ m_provider(provider),
+ m_requestedPort(NO_PORT_REQUESTED)
+ {
+ }
+
+ /// @brief Class copy constructor.
+ ///
+ /// @param[in] other Other class to copy on construct here
+ Joystick(const Joystick& other) : Peripheral(other) { *this = other; }
+
+ /// @brief Destructor.
+ ///
+ ~Joystick(void) override = default;
+
+ /// @brief Copy data from another @ref Joystick class to here.
+ ///
+ /// @param[in] other Other class to copy here
+ Joystick& operator=(const Joystick& rhs)
+ {
+ if (this != &rhs)
+ {
+ Peripheral::operator=(rhs);
+
+ m_provider = rhs.m_provider;
+ m_requestedPort = rhs.m_requestedPort;
+ m_buttonCount = rhs.m_buttonCount;
+ m_hatCount = rhs.m_hatCount;
+ m_axisCount = rhs.m_axisCount;
+ m_motorCount = rhs.m_motorCount;
+ m_supportsPowerOff = rhs.m_supportsPowerOff;
+ }
+ return *this;
+ }
+
+ /// @brief Get provider name.
+ ///
+ /// @return Name of provider
+ const std::string& Provider(void) const { return m_provider; }
+
+ /// @brief Get requested port number.
+ ///
+ /// @return Port
+ int RequestedPort(void) const { return m_requestedPort; }
+
+ /// @brief Get button count.
+ ///
+ /// @return Button count
+ unsigned int ButtonCount(void) const { return m_buttonCount; }
+
+ /// @brief Get hat count.
+ ///
+ /// @return Hat count
+ unsigned int HatCount(void) const { return m_hatCount; }
+
+ /// @brief Get axis count.
+ ///
+ /// @return Axis count
+ unsigned int AxisCount(void) const { return m_axisCount; }
+
+ /// @brief Get motor count.
+ ///
+ /// @return Motor count
+ unsigned int MotorCount(void) const { return m_motorCount; }
+
+ /// @brief Get supports power off.
+ ///
+ /// @return True if power off is supported, false otherwise
+ bool SupportsPowerOff(void) const { return m_supportsPowerOff; }
+
+ /// @brief Set provider name.
+ ///
+ /// @param[in] provider Name of provider
+ void SetProvider(const std::string& provider) { m_provider = provider; }
+
+ /// @brief Get requested port number.
+ ///
+ /// @param[in] requestedPort Port
+ void SetRequestedPort(int requestedPort) { m_requestedPort = requestedPort; }
+
+ /// @brief Get button count.
+ ///
+ /// @param[in] buttonCount Button count
+ void SetButtonCount(unsigned int buttonCount) { m_buttonCount = buttonCount; }
+
+ /// @brief Get hat count.
+ ///
+ /// @param[in] hatCount Hat count
+ void SetHatCount(unsigned int hatCount) { m_hatCount = hatCount; }
+
+ /// @brief Get axis count.
+ ///
+ /// @param[in] axisCount Axis count
+ void SetAxisCount(unsigned int axisCount) { m_axisCount = axisCount; }
+
+ /// @brief Get motor count.
+ ///
+ /// @param[in] motorCount Motor count
+ void SetMotorCount(unsigned int motorCount) { m_motorCount = motorCount; }
+
+ /// @brief Get supports power off.
+ ///
+ /// @param[in] supportsPowerOff True if power off is supported, false otherwise
+ void SetSupportsPowerOff(bool supportsPowerOff) { m_supportsPowerOff = supportsPowerOff; }
+
+ ///@}
+
+ explicit Joystick(const JOYSTICK_INFO& info)
+ : Peripheral(info.peripheral),
+ m_provider(info.provider ? info.provider : ""),
+ m_requestedPort(info.requested_port),
+ m_buttonCount(info.button_count),
+ m_hatCount(info.hat_count),
+ m_axisCount(info.axis_count),
+ m_motorCount(info.motor_count),
+ m_supportsPowerOff(info.supports_poweroff)
+ {
+ }
+
+ void ToStruct(JOYSTICK_INFO& info) const
+ {
+ Peripheral::ToStruct(info.peripheral);
+
+ info.provider = new char[m_provider.size() + 1];
+ info.requested_port = m_requestedPort;
+ info.button_count = m_buttonCount;
+ info.hat_count = m_hatCount;
+ info.axis_count = m_axisCount;
+ info.motor_count = m_motorCount;
+ info.supports_poweroff = m_supportsPowerOff;
+
+ std::strcpy(info.provider, m_provider.c_str());
+ }
+
+ static void FreeStruct(JOYSTICK_INFO& info)
+ {
+ Peripheral::FreeStruct(info.peripheral);
+
+ PERIPHERAL_SAFE_DELETE_ARRAY(info.provider);
+ }
+
+private:
+ std::string m_provider;
+ int m_requestedPort;
+ unsigned int m_buttonCount = 0;
+ unsigned int m_hatCount = 0;
+ unsigned int m_axisCount = 0;
+ unsigned int m_motorCount = 0;
+ bool m_supportsPowerOff = false;
+};
+///@}
+//------------------------------------------------------------------------------
+
+typedef PeripheralVector<Joystick, JOYSTICK_INFO> Joysticks;
+
+class JoystickFeature;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_DriverPrimitive class DriverPrimitive
+/// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+/// @brief **Base class for joystick driver primitives**
+///
+/// A driver primitive can be:
+///
+/// 1. a button
+/// 2. a hat direction
+/// 3. a semiaxis (either the positive or negative half of an axis)
+/// 4. a motor
+/// 5. a keyboard key
+/// 6. a mouse button
+/// 7. a relative pointer direction
+///
+/// The type determines the fields in use:
+///
+/// Button:
+/// - driver index
+///
+/// Hat direction:
+/// - driver index
+/// - hat direction
+///
+/// Semiaxis:
+/// - driver index
+/// - center
+/// - semiaxis direction
+/// - range
+///
+/// Motor:
+/// - driver index
+///
+/// Key:
+/// - key code
+///
+/// Mouse button:
+/// - driver index
+///
+/// Relative pointer direction:
+/// - relative pointer direction
+///
+///@{
+struct DriverPrimitive
+{
+protected:
+ /*!
+ * @brief Construct a driver primitive of the specified type
+ */
+ DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE type, unsigned int driverIndex)
+ : m_type(type), m_driverIndex(driverIndex)
+ {
+ }
+
+public:
+ /// @addtogroup cpp_kodi_addon_peripheral_Defs_Joystick_DriverPrimitive
+ ///@{
+
+ /// @brief Construct an invalid driver primitive.
+ DriverPrimitive(void) = default;
+
+ /// @brief Construct a driver primitive representing a joystick button.
+ ///
+ /// @param[in] buttonIndex Index
+ /// @return Created class
+ static DriverPrimitive CreateButton(unsigned int buttonIndex)
+ {
+ return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON, buttonIndex);
+ }
+
+ /// @brief Construct a driver primitive representing one of the four direction
+ /// arrows on a dpad.
+ ///
+ /// @param[in] hatIndex Hat index
+ /// @param[in] direction With @ref JOYSTICK_DRIVER_HAT_DIRECTION defined direction
+ DriverPrimitive(unsigned int hatIndex, JOYSTICK_DRIVER_HAT_DIRECTION direction)
+ : m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION),
+ m_driverIndex(hatIndex),
+ m_hatDirection(direction)
+ {
+ }
+
+ /// @brief Construct a driver primitive representing the positive or negative
+ /// half of an axis.
+ ///
+ /// @param[in] axisIndex Axis index
+ /// @param[in] center Center
+ /// @param[in] direction With @ref JOYSTICK_DRIVER_HAT_DIRECTION defined direction
+ /// @param[in] range Range
+ DriverPrimitive(unsigned int axisIndex,
+ int center,
+ JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction,
+ unsigned int range)
+ : m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS),
+ m_driverIndex(axisIndex),
+ m_center(center),
+ m_semiAxisDirection(direction),
+ m_range(range)
+ {
+ }
+
+ /// @brief Construct a driver primitive representing a motor.
+ ///
+ /// @param[in] motorIndex Motor index number
+ /// @return Constructed driver primitive representing a motor
+ static DriverPrimitive CreateMotor(unsigned int motorIndex)
+ {
+ return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR, motorIndex);
+ }
+
+ /// @brief Construct a driver primitive representing a key on a keyboard.
+ ///
+ /// @param[in] keycode Keycode to use
+ DriverPrimitive(std::string keycode)
+ : m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY), m_keycode(std::move(keycode))
+ {
+ }
+
+ /// @brief Construct a driver primitive representing a mouse button.
+ ///
+ /// @param[in] buttonIndex Index
+ /// @return Constructed driver primitive representing a mouse button
+ static DriverPrimitive CreateMouseButton(JOYSTICK_DRIVER_MOUSE_INDEX buttonIndex)
+ {
+ return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON,
+ static_cast<unsigned int>(buttonIndex));
+ }
+
+ /// @brief Construct a driver primitive representing one of the four
+ /// direction in which a relative pointer can move
+ ///
+ /// @param[in] direction With @ref JOYSTICK_DRIVER_RELPOINTER_DIRECTION defined direction
+ DriverPrimitive(JOYSTICK_DRIVER_RELPOINTER_DIRECTION direction)
+ : m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION), m_relPointerDirection(direction)
+ {
+ }
+
+ /// @brief Get type of primitive.
+ ///
+ /// @return The with @ref JOYSTICK_DRIVER_PRIMITIVE_TYPE defined type
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE Type(void) const { return m_type; }
+
+ /// @brief Get driver index.
+ ///
+ /// @return Index number
+ unsigned int DriverIndex(void) const { return m_driverIndex; }
+
+ /// @brief Get hat direction
+ ///
+ /// @return The with @ref JOYSTICK_DRIVER_HAT_DIRECTION defined direction
+ JOYSTICK_DRIVER_HAT_DIRECTION HatDirection(void) const { return m_hatDirection; }
+
+ /// @brief Get center
+ ///
+ /// @return Center
+ int Center(void) const { return m_center; }
+
+ /// @brief Get semi axis direction
+ ///
+ /// @return With @ref JOYSTICK_DRIVER_SEMIAXIS_DIRECTION defined direction
+ JOYSTICK_DRIVER_SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; }
+
+ /// @brief Get range.
+ ///
+ /// @return Range
+ unsigned int Range(void) const { return m_range; }
+
+ /// @brief Get key code as string.
+ ///
+ /// @return Key code
+ const std::string& Keycode(void) const { return m_keycode; }
+
+ /// @brief Get mouse index
+ ///
+ /// @return With @ref JOYSTICK_DRIVER_MOUSE_INDEX defined mouse index
+ JOYSTICK_DRIVER_MOUSE_INDEX MouseIndex(void) const
+ {
+ return static_cast<JOYSTICK_DRIVER_MOUSE_INDEX>(m_driverIndex);
+ }
+
+ /// @brief Get relative pointer direction.
+ ///
+ /// @return With @ref JOYSTICK_DRIVER_RELPOINTER_DIRECTION defined direction
+ JOYSTICK_DRIVER_RELPOINTER_DIRECTION RelPointerDirection(void) const
+ {
+ return m_relPointerDirection;
+ }
+
+ /// @brief Compare this with another class of this type.
+ ///
+ /// @param[in] other Other class to compare
+ /// @return True if they are equal, false otherwise
+ bool operator==(const DriverPrimitive& other) const
+ {
+ if (m_type == other.m_type)
+ {
+ switch (m_type)
+ {
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
+ {
+ return m_driverIndex == other.m_driverIndex;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
+ {
+ return m_driverIndex == other.m_driverIndex && m_hatDirection == other.m_hatDirection;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
+ {
+ return m_driverIndex == other.m_driverIndex && m_center == other.m_center &&
+ m_semiAxisDirection == other.m_semiAxisDirection && m_range == other.m_range;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY:
+ {
+ return m_keycode == other.m_keycode;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
+ {
+ return m_driverIndex == other.m_driverIndex;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
+ {
+ return m_driverIndex == other.m_driverIndex;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
+ {
+ return m_relPointerDirection == other.m_relPointerDirection;
+ }
+ default:
+ break;
+ }
+ }
+ return false;
+ }
+
+ ///@}
+
+ explicit DriverPrimitive(const JOYSTICK_DRIVER_PRIMITIVE& primitive) : m_type(primitive.type)
+ {
+ switch (m_type)
+ {
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
+ {
+ m_driverIndex = primitive.button.index;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
+ {
+ m_driverIndex = primitive.hat.index;
+ m_hatDirection = primitive.hat.direction;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
+ {
+ m_driverIndex = primitive.semiaxis.index;
+ m_center = primitive.semiaxis.center;
+ m_semiAxisDirection = primitive.semiaxis.direction;
+ m_range = primitive.semiaxis.range;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
+ {
+ m_driverIndex = primitive.motor.index;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY:
+ {
+ m_keycode = primitive.key.keycode;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
+ {
+ m_driverIndex = primitive.mouse.button;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
+ {
+ m_relPointerDirection = primitive.relpointer.direction;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ void ToStruct(JOYSTICK_DRIVER_PRIMITIVE& driver_primitive) const
+ {
+ driver_primitive.type = m_type;
+ switch (m_type)
+ {
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
+ {
+ driver_primitive.button.index = m_driverIndex;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
+ {
+ driver_primitive.hat.index = m_driverIndex;
+ driver_primitive.hat.direction = m_hatDirection;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
+ {
+ driver_primitive.semiaxis.index = m_driverIndex;
+ driver_primitive.semiaxis.center = m_center;
+ driver_primitive.semiaxis.direction = m_semiAxisDirection;
+ driver_primitive.semiaxis.range = m_range;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
+ {
+ driver_primitive.motor.index = m_driverIndex;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY:
+ {
+ const size_t size = sizeof(driver_primitive.key.keycode);
+ std::strncpy(driver_primitive.key.keycode, m_keycode.c_str(), size - 1);
+ driver_primitive.key.keycode[size - 1] = '\0';
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
+ {
+ driver_primitive.mouse.button = static_cast<JOYSTICK_DRIVER_MOUSE_INDEX>(m_driverIndex);
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
+ {
+ driver_primitive.relpointer.direction = m_relPointerDirection;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ static void FreeStruct(JOYSTICK_DRIVER_PRIMITIVE& primitive) { (void)primitive; }
+
+private:
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE m_type = JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN;
+ unsigned int m_driverIndex = 0;
+ JOYSTICK_DRIVER_HAT_DIRECTION m_hatDirection = JOYSTICK_DRIVER_HAT_UNKNOWN;
+ int m_center = 0;
+ JOYSTICK_DRIVER_SEMIAXIS_DIRECTION m_semiAxisDirection = JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN;
+ unsigned int m_range = 1;
+ std::string m_keycode;
+ JOYSTICK_DRIVER_RELPOINTER_DIRECTION m_relPointerDirection = JOYSTICK_DRIVER_RELPOINTER_UNKNOWN;
+};
+///@}
+//------------------------------------------------------------------------------
+
+typedef PeripheralVector<DriverPrimitive, JOYSTICK_DRIVER_PRIMITIVE> DriverPrimitives;
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JoystickFeature class JoystickFeature
+/// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+/// @brief **Base class for joystick feature primitives**
+///
+/// Class for joystick features. A feature can be:
+///
+/// 1. scalar *[1]*
+/// 2. analog stick
+/// 3. accelerometer
+/// 4. motor
+/// 5. relative pointer *[2]*
+/// 6. absolute pointer
+/// 7. wheel
+/// 8. throttle
+/// 9. keyboard key
+///
+/// *[1]* All three driver primitives (buttons, hats and axes) have a state that
+/// can be represented using a single scalar value. For this reason,
+/// features that map to a single primitive are called "scalar features".
+///
+/// *[2]* Relative pointers are similar to analog sticks, but they use
+/// relative distances instead of positions.
+///
+///@{
+class JoystickFeature
+{
+public:
+ /// @addtogroup cpp_kodi_addon_peripheral_Defs_Joystick_JoystickFeature
+ ///@{
+
+ /// @brief Class constructor.
+ ///
+ /// @param[in] name [optional] Name of the feature
+ /// @param[in] type [optional] Type of the feature, @ref JOYSTICK_FEATURE_TYPE_UNKNOWN
+ /// as default
+ JoystickFeature(const std::string& name = "",
+ JOYSTICK_FEATURE_TYPE type = JOYSTICK_FEATURE_TYPE_UNKNOWN)
+ : m_name(name), m_type(type), m_primitives{}
+ {
+ }
+
+ /// @brief Class copy constructor.
+ ///
+ /// @param[in] other Other class to copy on construct here
+ JoystickFeature(const JoystickFeature& other) { *this = other; }
+
+ /// @brief Copy data from another @ref JoystickFeature class to here.
+ ///
+ /// @param[in] other Other class to copy here
+ JoystickFeature& operator=(const JoystickFeature& rhs)
+ {
+ if (this != &rhs)
+ {
+ m_name = rhs.m_name;
+ m_type = rhs.m_type;
+ m_primitives = rhs.m_primitives;
+ }
+ return *this;
+ }
+
+ /// @brief Compare this with another class of this type.
+ ///
+ /// @param[in] other Other class to compare
+ /// @return True if they are equal, false otherwise
+ bool operator==(const JoystickFeature& other) const
+ {
+ return m_name == other.m_name && m_type == other.m_type && m_primitives == other.m_primitives;
+ }
+
+ /// @brief Get name of feature.
+ ///
+ /// @return Name of feature
+ const std::string& Name(void) const { return m_name; }
+
+ /// @brief Get name of feature.
+ ///
+ /// @return Type of feature defined with @ref JOYSTICK_FEATURE_TYPE
+ JOYSTICK_FEATURE_TYPE Type(void) const { return m_type; }
+
+ /// @brief Check this feature is valid.
+ ///
+ /// @return True if valid (type != JOYSTICK_FEATURE_TYPE_UNKNOWN), false otherwise
+ bool IsValid() const { return m_type != JOYSTICK_FEATURE_TYPE_UNKNOWN; }
+
+ /// @brief Set name of feature.
+ ///
+ /// @param[in] name Name of feature
+ void SetName(const std::string& name) { m_name = name; }
+
+ /// @brief Set type of feature.
+ ///
+ /// @param[in] type Type of feature
+ void SetType(JOYSTICK_FEATURE_TYPE type) { m_type = type; }
+
+ /// @brief Set type as invalid.
+ void SetInvalid(void) { m_type = JOYSTICK_FEATURE_TYPE_UNKNOWN; }
+
+ /// @brief Get primitive of feature by wanted type.
+ ///
+ /// @param[in] which Type of feature, defined with @ref JOYSTICK_FEATURE_PRIMITIVE
+ /// @return Primitive of asked type
+ const DriverPrimitive& Primitive(JOYSTICK_FEATURE_PRIMITIVE which) const
+ {
+ return m_primitives[which];
+ }
+
+ /// @brief Set primitive for feature by wanted type.
+ ///
+ /// @param[in] which Type of feature, defined with @ref JOYSTICK_FEATURE_PRIMITIVE
+ /// @param[in] primitive The with @ref DriverPrimitive defined primitive to set
+ void SetPrimitive(JOYSTICK_FEATURE_PRIMITIVE which, const DriverPrimitive& primitive)
+ {
+ m_primitives[which] = primitive;
+ }
+
+ /// @brief Get all primitives on this class.
+ ///
+ /// @return Array list of primitives
+ std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX>& Primitives() { return m_primitives; }
+
+ /// @brief Get all primitives on this class (as constant).
+ ///
+ /// @return Constant a´rray list of primitives
+ const std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX>& Primitives() const
+ {
+ return m_primitives;
+ }
+
+ ///@}
+
+ 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] = DriverPrimitive(feature.primitives[i]);
+ }
+
+ void ToStruct(JOYSTICK_FEATURE& feature) const
+ {
+ feature.name = new char[m_name.length() + 1];
+ feature.type = m_type;
+ for (unsigned int i = 0; i < JOYSTICK_PRIMITIVE_MAX; i++)
+ m_primitives[i].ToStruct(feature.primitives[i]);
+
+ std::strcpy(feature.name, m_name.c_str());
+ }
+
+ static void FreeStruct(JOYSTICK_FEATURE& feature) { PERIPHERAL_SAFE_DELETE_ARRAY(feature.name); }
+
+private:
+ std::string m_name;
+ JOYSTICK_FEATURE_TYPE m_type;
+ std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX> m_primitives;
+};
+///@}
+//------------------------------------------------------------------------------
+
+typedef PeripheralVector<JoystickFeature, JOYSTICK_FEATURE> JoystickFeatures;
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/CMakeLists.txt
new file mode 100644
index 0000000..1690c39
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ ChannelGroups.h
+ Channels.h
+ EDL.h
+ EPG.h
+ General.h
+ MenuHook.h
+ Providers.h
+ Recordings.h
+ Stream.h
+ Timers.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_addon-instance_pvr)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/ChannelGroups.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/ChannelGroups.h
new file mode 100644
index 0000000..37340bf
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/ChannelGroups.h
@@ -0,0 +1,271 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 3 - PVR channel group
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup class PVRChannelGroup
+/// @ingroup cpp_kodi_addon_pvr_Defs_ChannelGroup
+/// @brief **PVR add-on channel group**\n
+/// To define a group for channels, this becomes be asked from
+/// @ref kodi::addon::CInstancePVRClient::GetChannelGroups() and used on
+/// @ref kodi::addon::CInstancePVRClient::GetChannelGroupMembers() to get his
+/// content with @ref cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember "PVRChannelGroupMember".
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup_Help
+///
+///@{
+class PVRChannelGroup : public CStructHdl<PVRChannelGroup, PVR_CHANNEL_GROUP>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRChannelGroup() { memset(m_cStructure, 0, sizeof(PVR_CHANNEL_GROUP)); }
+ PVRChannelGroup(const PVRChannelGroup& channel) : CStructHdl(channel) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Group name** | `std::string` | @ref PVRChannelGroup::SetGroupName "SetGroupName" | @ref PVRChannelGroup::GetGroupName "GetGroupName" | *required to set*
+ /// | **Is radio** | `bool` | @ref PVRChannelGroup::SetIsRadio "SetIsRadio" | @ref PVRChannelGroup::GetIsRadio "GetIsRadio" | *required to set*
+ /// | **Position** | `unsigned int` | @ref PVRChannelGroup::SetPosition "SetPosition" | @ref PVRChannelGroup::GetPosition "GetPosition" | *optional*
+ ///
+
+ /// @ingroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup
+ ///@{
+
+ /// @brief **required**\n
+ /// Name of this channel group.
+ void SetGroupName(const std::string& groupName)
+ {
+ strncpy(m_cStructure->strGroupName, groupName.c_str(), sizeof(m_cStructure->strGroupName) - 1);
+ }
+
+ /// @brief To get with @ref SetGroupName changed values.
+ std::string GetGroupName() const { return m_cStructure->strGroupName; }
+
+ /// @brief **required**\n
+ /// **true** If this is a radio channel group, **false** otherwise.
+ void SetIsRadio(bool isRadio) { m_cStructure->bIsRadio = isRadio; }
+
+ /// @brief To get with @ref SetIsRadio changed values.
+ bool GetIsRadio() const { return m_cStructure->bIsRadio; }
+
+ /// @brief **optional**\n
+ /// Sort position of the group (<b>`0`</b> indicates that the backend doesn't
+ /// support sorting of groups).
+ void SetPosition(unsigned int position) { m_cStructure->iPosition = position; }
+
+ /// @brief To get with @ref SetPosition changed values.
+ unsigned int GetPosition() const { return m_cStructure->iPosition; }
+
+ ///@}
+
+private:
+ PVRChannelGroup(const PVR_CHANNEL_GROUP* channel) : CStructHdl(channel) {}
+ PVRChannelGroup(PVR_CHANNEL_GROUP* channel) : CStructHdl(channel) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupsResultSet class PVRChannelGroupsResultSet
+/// @ingroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroup
+/// @brief **PVR add-on channel group member transfer class**\n
+/// To transfer the content of @ref kodi::addon::CInstancePVRClient::GetChannelGroups().
+///
+///@{
+class PVRChannelGroupsResultSet
+{
+public:
+ /*! \cond PRIVATE */
+ PVRChannelGroupsResultSet() = delete;
+ PVRChannelGroupsResultSet(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ : m_instance(instance), m_handle(handle)
+ {
+ }
+ /*! \endcond */
+
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupsResultSet
+ ///@{
+
+ /// @brief To add and give content from addon to Kodi on related call.
+ ///
+ /// @param[in] tag The to transferred data.
+ void Add(const kodi::addon::PVRChannelGroup& tag)
+ {
+ m_instance->toKodi->TransferChannelGroup(m_instance->toKodi->kodiInstance, m_handle, tag);
+ }
+
+ ///@}
+
+private:
+ const AddonInstance_PVR* m_instance = nullptr;
+ const PVR_HANDLE m_handle;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember class PVRChannelGroupMember
+/// @ingroup cpp_kodi_addon_pvr_Defs_ChannelGroup
+/// @brief **PVR add-on channel group member**\n
+/// To define the content of @ref kodi::addon::CInstancePVRClient::GetChannelGroups()
+/// given groups.
+///
+/// This content becomes then requested with @ref kodi::addon::CInstancePVRClient::GetChannelGroupMembers().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember_Help
+///
+///@{
+class PVRChannelGroupMember : public CStructHdl<PVRChannelGroupMember, PVR_CHANNEL_GROUP_MEMBER>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRChannelGroupMember() { memset(m_cStructure, 0, sizeof(PVR_CHANNEL_GROUP_MEMBER)); }
+ PVRChannelGroupMember(const PVRChannelGroupMember& channel) : CStructHdl(channel) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |-------|-------|-----------|----------|-----------
+ /// | **Group name** | `std::string` | @ref PVRChannelGroupMember::SetGroupName "SetGroupName" | @ref PVRChannelGroupMember::GetGroupName "GetGroupName" | *required to set*
+ /// | **Channel unique id** | `unsigned int` | @ref PVRChannelGroupMember::SetChannelUniqueId "SetChannelUniqueId" | @ref PVRChannelGroupMember::GetChannelUniqueId "GetChannelUniqueId" | *required to set*
+ /// | **Channel Number** | `unsigned int` | @ref PVRChannelGroupMember::SetChannelNumber "SetChannelNumber" | @ref PVRChannelGroupMember::GetChannelNumber "GetChannelNumber" | *optional*
+ /// | **Sub channel number** | `unsigned int` | @ref PVRChannelGroupMember::SetSubChannelNumber "SetSubChannelNumber"| @ref PVRChannelGroupMember::GetSubChannelNumber "GetSubChannelNumber" | *optional*
+ /// | **Order** | `int` | @ref PVRChannel::SetOrder "SetOrder" | @ref PVRChannel::GetOrder "GetOrder" | *optional*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember
+ ///@{
+
+ /// @brief **required**\n
+ /// Name of the channel group to add the channel to.
+ void SetGroupName(const std::string& groupName)
+ {
+ strncpy(m_cStructure->strGroupName, groupName.c_str(), sizeof(m_cStructure->strGroupName) - 1);
+ }
+
+ /// @brief To get with @ref SetGroupName changed values.
+ std::string GetGroupName() const { return m_cStructure->strGroupName; }
+
+ /// @brief **required**\n
+ /// Unique id of the member.
+ void SetChannelUniqueId(unsigned int channelUniqueId)
+ {
+ m_cStructure->iChannelUniqueId = channelUniqueId;
+ }
+
+ /// @brief To get with @ref SetChannelUniqueId changed values.
+ unsigned int GetChannelUniqueId() const { return m_cStructure->iChannelUniqueId; }
+
+ /// @brief **optional**\n
+ /// Channel number within the group.
+ void SetChannelNumber(unsigned int channelNumber)
+ {
+ m_cStructure->iChannelNumber = channelNumber;
+ }
+
+ /// @brief To get with @ref SetChannelNumber changed values.
+ unsigned int GetChannelNumber() const { return m_cStructure->iChannelNumber; }
+
+ /// @brief **optional**\n
+ /// Sub channel number within the group (ATSC).
+ void SetSubChannelNumber(unsigned int subChannelNumber)
+ {
+ m_cStructure->iSubChannelNumber = subChannelNumber;
+ }
+
+ /// @brief To get with @ref SetSubChannelNumber changed values.
+ unsigned int GetSubChannelNumber() const { return m_cStructure->iSubChannelNumber; }
+
+ /// @brief **optional**\n
+ /// The value denoting the order of this channel in the <b>'All channels'</b> group.
+ void SetOrder(bool order) { m_cStructure->iOrder = order; }
+
+ /// @brief To get with @ref SetOrder changed values.
+ bool GetOrder() const { return m_cStructure->iOrder; }
+
+ ///@}
+
+private:
+ PVRChannelGroupMember(const PVR_CHANNEL_GROUP_MEMBER* channel) : CStructHdl(channel) {}
+ PVRChannelGroupMember(PVR_CHANNEL_GROUP_MEMBER* channel) : CStructHdl(channel) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMembersResultSet class PVRChannelGroupMembersResultSet
+/// @ingroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMember
+/// @brief **PVR add-on channel group member transfer class**\n
+/// To transfer the content of @ref kodi::addon::CInstancePVRClient::GetChannelGroupMembers().
+///
+///@{
+class PVRChannelGroupMembersResultSet
+{
+public:
+ /*! \cond PRIVATE */
+ PVRChannelGroupMembersResultSet() = delete;
+ PVRChannelGroupMembersResultSet(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ : m_instance(instance), m_handle(handle)
+ {
+ }
+ /*! \endcond */
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_ChannelGroup_PVRChannelGroupMembersResultSet
+ ///@{
+
+ /// @brief To add and give content from addon to Kodi on related call.
+ ///
+ /// @param[in] tag The to transferred data.
+ void Add(const kodi::addon::PVRChannelGroupMember& tag)
+ {
+ m_instance->toKodi->TransferChannelGroupMember(m_instance->toKodi->kodiInstance, m_handle, tag);
+ }
+
+ ///@}
+
+private:
+ const AddonInstance_PVR* m_instance = nullptr;
+ const PVR_HANDLE m_handle;
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Channels.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Channels.h
new file mode 100644
index 0000000..d59803d
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Channels.h
@@ -0,0 +1,535 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 2 - PVR channel
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVRChannel class PVRChannel
+/// @ingroup cpp_kodi_addon_pvr_Defs_Channel
+/// @brief **Channel data structure**\n
+/// Representation of a TV or radio channel.
+///
+/// This is used to store all the necessary TV or radio channel data and can
+/// either provide the necessary data from / to Kodi for the associated
+/// functions or can also be used in the addon to store its data.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRChannel_Help
+///
+///@{
+class PVRChannel : public CStructHdl<PVRChannel, PVR_CHANNEL>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRChannel()
+ {
+ memset(m_cStructure, 0, sizeof(PVR_CHANNEL));
+ m_cStructure->iClientProviderUid = PVR_PROVIDER_INVALID_UID;
+ }
+ PVRChannel(const PVRChannel& channel) : CStructHdl(channel) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVRChannel_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Channel_PVRChannel
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Channel_PVRChannel :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Unique id** | `unsigned int` | @ref PVRChannel::SetUniqueId "SetUniqueId" | @ref PVRChannel::GetUniqueId "GetUniqueId" | *required to set*
+ /// | **Is radio** | `bool` | @ref PVRChannel::SetIsRadio "SetIsRadio" | @ref PVRChannel::GetIsRadio "GetIsRadio" | *required to set*
+ /// | **Channel number** | `unsigned int` | @ref PVRChannel::SetChannelNumber "SetChannelNumber" | @ref PVRChannel::GetChannelNumber "GetChannelNumber" | *optional*
+ /// | **Sub channel number** | `unsigned int` | @ref PVRChannel::SetSubChannelNumber "SetSubChannelNumber" | @ref PVRChannel::GetSubChannelNumber "GetSubChannelNumber" | *optional*
+ /// | **Channel name** | `std::string` | @ref PVRChannel::SetChannelName "SetChannelName" | @ref PVRChannel::GetChannelName "GetChannelName" | *optional*
+ /// | **Mime type** | `std::string` | @ref PVRChannel::SetMimeType "SetMimeType" | @ref PVRChannel::GetMimeType "GetMimeType" | *optional*
+ /// | **Encryption system** | `unsigned int` | @ref PVRChannel::SetEncryptionSystem "SetEncryptionSystem" | @ref PVRChannel::GetEncryptionSystem "GetEncryptionSystem" | *optional*
+ /// | **Icon path** | `std::string` | @ref PVRChannel::SetIconPath "SetIconPath" | @ref PVRChannel::GetIconPath "GetIconPath" | *optional*
+ /// | **Is hidden** | `bool` | @ref PVRChannel::SetIsHidden "SetIsHidden" | @ref PVRChannel::GetIsHidden "GetIsHidden" | *optional*
+ /// | **Has archive** | `bool` | @ref PVRChannel::SetHasArchive "SetHasArchive" | @ref PVRChannel::GetHasArchive "GetHasArchive" | *optional*
+ /// | **Order** | `int` | @ref PVRChannel::SetOrder "SetOrder" | @ref PVRChannel::GetOrder "GetOrder" | *optional*
+ /// | **Client provider unique identifier** | `int` | @ref PVRChannel::SetClientProviderUid "SetClientProviderUid" | @ref PVRTimer::GetClientProviderUid "GetClientProviderUid" | *optional*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Channel_PVRChannel
+ ///@{
+
+ /// @brief **required**\n
+ /// Unique identifier for this channel.
+ void SetUniqueId(unsigned int uniqueId) { m_cStructure->iUniqueId = uniqueId; }
+
+ /// @brief To get with @ref SetUniqueId changed values.
+ unsigned int GetUniqueId() const { return m_cStructure->iUniqueId; }
+
+ /// @brief **required**\n
+ /// **true** if this is a radio channel, **false** if it's a TV channel.
+ void SetIsRadio(bool isRadio) { m_cStructure->bIsRadio = isRadio; }
+
+ /// @brief To get with @ref SetIsRadio changed values.
+ bool GetIsRadio() const { return m_cStructure->bIsRadio; }
+
+ /// @brief **optional**\n
+ /// Channel number of this channel on the backend.
+ void SetChannelNumber(unsigned int channelNumber)
+ {
+ m_cStructure->iChannelNumber = channelNumber;
+ }
+
+ /// @brief To get with @ref SetChannelNumber changed values.
+ unsigned int GetChannelNumber() const { return m_cStructure->iChannelNumber; }
+
+ /// @brief **optional**\n
+ /// Sub channel number of this channel on the backend (ATSC).
+ void SetSubChannelNumber(unsigned int subChannelNumber)
+ {
+ m_cStructure->iSubChannelNumber = subChannelNumber;
+ }
+
+ /// @brief To get with @ref SetSubChannelNumber changed values.
+ unsigned int GetSubChannelNumber() const { return m_cStructure->iSubChannelNumber; }
+
+ /// @brief **optional**\n
+ /// Channel name given to this channel.
+ void SetChannelName(const std::string& channelName)
+ {
+ strncpy(m_cStructure->strChannelName, channelName.c_str(),
+ sizeof(m_cStructure->strChannelName) - 1);
+ }
+
+ /// @brief To get with @ref SetChannelName changed values.
+ std::string GetChannelName() const { return m_cStructure->strChannelName; }
+
+ /// @brief **optional**\n
+ /// Input format mime type.
+ ///
+ /// Available types can be found in https://www.iana.org/assignments/media-types/media-types.xhtml
+ /// on "application" and "video" or leave empty if unknown.
+ ///
+ void SetMimeType(const std::string& inputFormat)
+ {
+ strncpy(m_cStructure->strMimeType, inputFormat.c_str(), sizeof(m_cStructure->strMimeType) - 1);
+ }
+
+ /// @brief To get with @ref SetMimeType changed values.
+ std::string GetMimeType() const { return m_cStructure->strMimeType; }
+
+ /// @brief **optional**\n
+ /// The encryption ID or CaID of this channel (Conditional access systems).
+ ///
+ /// Lists about available ID's:
+ /// - http://www.dvb.org/index.php?id=174
+ /// - http://en.wikipedia.org/wiki/Conditional_access_system
+ ///
+ void SetEncryptionSystem(unsigned int encryptionSystem)
+ {
+ m_cStructure->iEncryptionSystem = encryptionSystem;
+ }
+
+ /// @brief To get with @ref SetEncryptionSystem changed values.
+ unsigned int GetEncryptionSystem() const { return m_cStructure->iEncryptionSystem; }
+
+ /// @brief **optional**\n
+ /// Path to the channel icon (if present).
+ void SetIconPath(const std::string& iconPath)
+ {
+ strncpy(m_cStructure->strIconPath, iconPath.c_str(), sizeof(m_cStructure->strIconPath) - 1);
+ }
+
+ /// @brief To get with @ref SetIconPath changed values.
+ std::string GetIconPath() const { return m_cStructure->strIconPath; }
+
+ /// @brief **optional**\n
+ /// **true** if this channel is marked as hidden.
+ void SetIsHidden(bool isHidden) { m_cStructure->bIsHidden = isHidden; }
+
+ /// @brief To get with @ref GetIsRadio changed values.
+ bool GetIsHidden() const { return m_cStructure->bIsHidden; }
+
+ /// @brief **optional**\n
+ /// **true** if this channel has a server-side back buffer.
+ void SetHasArchive(bool hasArchive) { m_cStructure->bHasArchive = hasArchive; }
+
+ /// @brief To get with @ref GetIsRadio changed values.
+ bool GetHasArchive() const { return m_cStructure->bHasArchive; }
+
+ /// @brief **optional**\n
+ /// The value denoting the order of this channel in the 'All channels' group.
+ void SetOrder(bool order) { m_cStructure->iOrder = order; }
+
+ /// @brief To get with @ref SetOrder changed values.
+ bool GetOrder() const { return m_cStructure->iOrder; }
+ ///@}
+
+ /// @brief **optional**\n
+ /// Unique identifier of the provider this channel belongs to.
+ ///
+ /// @ref PVR_PROVIDER_INVALID_UID denotes that provider uid is not available.
+ void SetClientProviderUid(int iClientProviderUid)
+ {
+ m_cStructure->iClientProviderUid = iClientProviderUid;
+ }
+
+ /// @brief To get with @ref SetClientProviderUid changed values
+ int GetClientProviderUid() const { return m_cStructure->iClientProviderUid; }
+
+private:
+ PVRChannel(const PVR_CHANNEL* channel) : CStructHdl(channel) {}
+ PVRChannel(PVR_CHANNEL* channel) : CStructHdl(channel) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVRChannelsResultSet class PVRChannelsResultSet
+/// @ingroup cpp_kodi_addon_pvr_Defs_Channel_PVRChannel
+/// @brief **PVR add-on channel transfer class**\n
+/// To transfer the content of @ref kodi::addon::CInstancePVRClient::GetChannels().
+///
+///@{
+class PVRChannelsResultSet
+{
+public:
+ /*! \cond PRIVATE */
+ PVRChannelsResultSet() = delete;
+ PVRChannelsResultSet(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ : m_instance(instance), m_handle(handle)
+ {
+ }
+ /*! \endcond */
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Channel_PVRChannelsResultSet
+ ///@{
+
+ /// @brief To add and give content from addon to Kodi on related call.
+ ///
+ /// @param[in] tag The to transferred data.
+ void Add(const kodi::addon::PVRChannel& tag)
+ {
+ m_instance->toKodi->TransferChannelEntry(m_instance->toKodi->kodiInstance, m_handle, tag);
+ }
+
+ ///@}
+
+private:
+ const AddonInstance_PVR* m_instance = nullptr;
+ const PVR_HANDLE m_handle;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus class PVRSignalStatus
+/// @ingroup cpp_kodi_addon_pvr_Defs_Channel
+/// @brief **PVR Signal status information**\n
+/// This class gives current status information from stream to Kodi.
+///
+/// Used to get information for user by call of @ref kodi::addon::CInstancePVRClient::GetSignalStatus()
+/// to see current quality and source.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus_Help
+///
+///@{
+class PVRSignalStatus : public CStructHdl<PVRSignalStatus, PVR_SIGNAL_STATUS>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRSignalStatus() = default;
+ PVRSignalStatus(const PVRSignalStatus& type) : CStructHdl(type) {}
+ /*! \endcond */
+
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Adapter name** | `std::string` | @ref PVRSignalStatus::SetAdapterName "SetAdapterName" | @ref PVRSignalStatus::GetAdapterName "GetAdapterName" | *optional*
+ /// | **Adapter status** | `std::string` | @ref PVRSignalStatus::SetAdapterStatus "SetAdapterStatus" | @ref PVRSignalStatus::GetAdapterStatus "GetAdapterStatus" | *optional*
+ /// | **Service name** | `std::string` | @ref PVRSignalStatus::SetServiceName "SetServiceName" | @ref PVRSignalStatus::GetServiceName "GetServiceName" | *optional*
+ /// | **Provider name** | `std::string` | @ref PVRSignalStatus::SetProviderName "SetProviderName" | @ref PVRSignalStatus::GetProviderName "GetProviderName" | *optional*
+ /// | **Mux name** | `std::string` | @ref PVRSignalStatus::SetMuxName "SetMuxName" | @ref PVRSignalStatus::GetMuxName "GetMuxName" | *optional*
+ /// | **Signal/noise ratio** | `int` | @ref PVRSignalStatus::SetSNR "SetSNR" | @ref PVRSignalStatus::GetSNR "GetSNR" | *optional*
+ /// | **Signal strength** | `int` | @ref PVRSignalStatus::SetSignal "SetSignal" | @ref PVRSignalStatus::GetSignal "GetSignal" | *optional*
+ /// | **Bit error rate** | `long` | @ref PVRSignalStatus::SetBER "SetBER" | @ref PVRSignalStatus::GetBER "GetBER" | *optional*
+ /// | **Uncorrected blocks** | `long` | @ref PVRSignalStatus::SetUNC "SetUNC" | @ref PVRSignalStatus::GetUNC "GetUNC" | *optional*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Channel_PVRSignalStatus
+ ///@{
+
+ /// @brief **optional**\n
+ /// Name of the adapter that's being used.
+ void SetAdapterName(const std::string& adapterName)
+ {
+ strncpy(m_cStructure->strAdapterName, adapterName.c_str(),
+ sizeof(m_cStructure->strAdapterName) - 1);
+ }
+
+ /// @brief To get with @ref SetAdapterName changed values.
+ std::string GetAdapterName() const { return m_cStructure->strAdapterName; }
+
+ /// @brief **optional**\n
+ /// Status of the adapter that's being used.
+ void SetAdapterStatus(const std::string& adapterStatus)
+ {
+ strncpy(m_cStructure->strAdapterStatus, adapterStatus.c_str(),
+ sizeof(m_cStructure->strAdapterStatus) - 1);
+ }
+
+ /// @brief To get with @ref SetAdapterStatus changed values.
+ std::string GetAdapterStatus() const { return m_cStructure->strAdapterStatus; }
+
+ /// @brief **optional**\n
+ /// Name of the current service.
+ void SetServiceName(const std::string& serviceName)
+ {
+ strncpy(m_cStructure->strServiceName, serviceName.c_str(),
+ sizeof(m_cStructure->strServiceName) - 1);
+ }
+
+ /// @brief To get with @ref SetServiceName changed values.
+ std::string GetServiceName() const { return m_cStructure->strServiceName; }
+
+ /// @brief **optional**\n
+ /// Name of the current service's provider.
+ void SetProviderName(const std::string& providerName)
+ {
+ strncpy(m_cStructure->strProviderName, providerName.c_str(),
+ sizeof(m_cStructure->strProviderName) - 1);
+ }
+
+ /// @brief To get with @ref SetProviderName changed values.
+ std::string GetProviderName() const { return m_cStructure->strProviderName; }
+
+ /// @brief **optional**\n
+ /// Name of the current mux.
+ void SetMuxName(const std::string& muxName)
+ {
+ strncpy(m_cStructure->strMuxName, muxName.c_str(), sizeof(m_cStructure->strMuxName) - 1);
+ }
+
+ /// @brief To get with @ref SetMuxName changed values.
+ std::string GetMuxName() const { return m_cStructure->strMuxName; }
+
+ /// @brief **optional**\n
+ /// Signal/noise ratio.
+ ///
+ /// @note 100% is 0xFFFF 65535
+ void SetSNR(int snr) { m_cStructure->iSNR = snr; }
+
+ /// @brief To get with @ref SetSNR changed values.
+ int GetSNR() const { return m_cStructure->iSNR; }
+
+ /// @brief **optional**\n
+ /// Signal strength.
+ ///
+ /// @note 100% is 0xFFFF 65535
+ void SetSignal(int signal) { m_cStructure->iSignal = signal; }
+
+ /// @brief To get with @ref SetSignal changed values.
+ int GetSignal() const { return m_cStructure->iSignal; }
+
+ /// @brief **optional**\n
+ /// Bit error rate.
+ void SetBER(long ber) { m_cStructure->iBER = ber; }
+
+ /// @brief To get with @ref SetBER changed values.
+ long GetBER() const { return m_cStructure->iBER; }
+
+ /// @brief **optional**\n
+ /// Uncorrected blocks:
+ void SetUNC(long unc) { m_cStructure->iUNC = unc; }
+
+ /// @brief To get with @ref SetBER changed values.
+ long GetUNC() const { return m_cStructure->iUNC; }
+ ///@}
+
+private:
+ PVRSignalStatus(const PVR_SIGNAL_STATUS* type) : CStructHdl(type) {}
+ PVRSignalStatus(PVR_SIGNAL_STATUS* type) : CStructHdl(type) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo class PVRDescrambleInfo
+/// @ingroup cpp_kodi_addon_pvr_Defs_Channel
+/// @brief **Data structure for descrample info**\n
+/// Information data to give via this to Kodi.
+///
+/// As description see also here https://en.wikipedia.org/wiki/Conditional_access.
+///
+/// Used on @ref kodi::addon::CInstancePVRClient::GetDescrambleInfo().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo_Help
+///
+///@{
+class PVRDescrambleInfo : public CStructHdl<PVRDescrambleInfo, PVR_DESCRAMBLE_INFO>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRDescrambleInfo()
+ {
+ m_cStructure->iPid = PVR_DESCRAMBLE_INFO_NOT_AVAILABLE;
+ m_cStructure->iCaid = PVR_DESCRAMBLE_INFO_NOT_AVAILABLE;
+ m_cStructure->iProvid = PVR_DESCRAMBLE_INFO_NOT_AVAILABLE;
+ m_cStructure->iEcmTime = PVR_DESCRAMBLE_INFO_NOT_AVAILABLE;
+ m_cStructure->iHops = PVR_DESCRAMBLE_INFO_NOT_AVAILABLE;
+ }
+ PVRDescrambleInfo(const PVRDescrambleInfo& type) : CStructHdl(type) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Packet identifier** | `int` | @ref PVRDescrambleInfo::SetPID "SetPID" | @ref PVRDescrambleInfo::GetPID "GetPID" | *optional*
+ /// | **Conditional access identifier** | `int` | @ref PVRDescrambleInfo::SetCAID "SetCAID" | @ref PVRDescrambleInfo::GetCAID "GetCAID" | *optional*
+ /// | **Provider-ID** | `int` | @ref PVRDescrambleInfo::SetProviderID "SetProviderID" | @ref PVRDescrambleInfo::GetProviderID "GetProviderID" | *optional*
+ /// | **ECM time** | `int` | @ref PVRDescrambleInfo::SetECMTime "SetECMTime" | @ref PVRDescrambleInfo::GetECMTime "GetECMTime" | *optional*
+ /// | **Hops** | `int` | @ref PVRDescrambleInfo::SetHops "SetHops" | @ref PVRDescrambleInfo::GetHops "GetHops" | *optional*
+ /// | **Descramble card system** | `std::string` | @ref PVRDescrambleInfo::SetHops "SetHops" | @ref PVRDescrambleInfo::GetHops "GetHops" | *optional*
+ /// | **Reader** | `std::string` | @ref PVRDescrambleInfo::SetReader "SetReader" | @ref PVRDescrambleInfo::GetReader "GetReader" | *optional*
+ /// | **From** | `std::string` | @ref PVRDescrambleInfo::SetFrom "SetFrom" | @ref PVRDescrambleInfo::GetFrom "GetFrom" | *optional*
+ /// | **Protocol** | `std::string` | @ref PVRDescrambleInfo::SetProtocol "SetProtocol" | @ref PVRDescrambleInfo::GetProtocol "GetProtocol" | *optional*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo
+ ///@{
+
+ /// @brief **optional**\n
+ /// Packet identifier.
+ ///
+ /// Each table or elementary stream in a transport stream is identified by
+ /// a 13-bit packet identifier (PID).
+ ///
+ /// Is @ref PVR_DESCRAMBLE_INFO_NOT_AVAILABLE as default, if not available
+ void SetPID(int pid) { m_cStructure->iPid = pid; }
+
+ /// @brief To get with @ref SetPID changed values
+ int GetPID() const { return m_cStructure->iPid; }
+
+ /// @brief **optional**\n
+ /// Conditional access identifier.
+ ///
+ /// Conditional access (abbreviated CA) or conditional access system (abbreviated CAS)
+ /// is the protection of content by requiring certain criteria to be met before granting
+ /// access to the content.
+ ///
+ /// Available CA system ID's listed here https://www.dvbservices.com/identifiers/ca_system_id.
+ ///
+ /// @ref PVR_DESCRAMBLE_INFO_NOT_AVAILABLE if not available.
+ void SetCAID(int iCaid) { m_cStructure->iCaid = iCaid; }
+
+ /// @brief To get with @ref SetCAID changed values.
+ int GetCAID() const { return m_cStructure->iCaid; }
+
+ /// @brief **optional**\n
+ /// Provider-ID.
+ ///
+ /// Is @ref PVR_DESCRAMBLE_INFO_NOT_AVAILABLE as default, if not available.
+ void SetProviderID(int provid) { m_cStructure->iProvid = provid; }
+
+ /// @brief To get with @ref SetProviderID changed values
+ int GetProviderID() const { return m_cStructure->iProvid; }
+
+ /// @brief **optional**\n
+ /// ECM time.
+ ///
+ /// Is @ref PVR_DESCRAMBLE_INFO_NOT_AVAILABLE as default, if not available.
+ void SetECMTime(int ecmTime) { m_cStructure->iEcmTime = ecmTime; }
+
+ /// @brief To get with @ref SetECMTime changed values.
+ int GetECMTime() const { return m_cStructure->iEcmTime; }
+
+ /// @brief **optional**\n
+ /// Hops.
+ ///
+ /// Is @ref PVR_DESCRAMBLE_INFO_NOT_AVAILABLE as default, if not available.
+ void SetHops(int hops) { m_cStructure->iHops = hops; }
+
+ /// @brief To get with @ref SetHops changed values.
+ int GetHops() const { return m_cStructure->iHops; }
+
+ /// @brief **optional**\n
+ /// Empty string if not available.
+ void SetCardSystem(const std::string& cardSystem)
+ {
+ strncpy(m_cStructure->strCardSystem, cardSystem.c_str(),
+ sizeof(m_cStructure->strCardSystem) - 1);
+ }
+
+ /// @brief To get with @ref SetCardSystem changed values.
+ std::string GetCardSystem() const { return m_cStructure->strCardSystem; }
+
+ /// @brief **optional**\n
+ /// Empty string if not available.
+ void SetReader(const std::string& reader)
+ {
+ strncpy(m_cStructure->strReader, reader.c_str(), sizeof(m_cStructure->strReader) - 1);
+ }
+
+ /// @brief To get with @ref SetReader changed values.
+ std::string GetReader() const { return m_cStructure->strReader; }
+
+ /// @brief **optional**\n
+ /// Empty string if not available.
+ void SetFrom(const std::string& from)
+ {
+ strncpy(m_cStructure->strFrom, from.c_str(), sizeof(m_cStructure->strFrom) - 1);
+ }
+
+ /// @brief To get with @ref SetFrom changed values.
+ std::string GetFrom() const { return m_cStructure->strFrom; }
+
+ /// @brief **optional**\n
+ /// Empty string if not available.
+ void SetProtocol(const std::string& protocol)
+ {
+ strncpy(m_cStructure->strProtocol, protocol.c_str(), sizeof(m_cStructure->strProtocol) - 1);
+ }
+
+ /// @brief To get with @ref SetProtocol changed values.
+ std::string GetProtocol() const { return m_cStructure->strProtocol; }
+ ///@}
+
+private:
+ PVRDescrambleInfo(const PVR_DESCRAMBLE_INFO* type) : CStructHdl(type) {}
+ PVRDescrambleInfo(PVR_DESCRAMBLE_INFO* type) : CStructHdl(type) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EDL.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EDL.h
new file mode 100644
index 0000000..34c7c41
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EDL.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr/pvr_edl.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 8 - PVR Edit definition list (EDL)
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry class PVREDLEntry
+/// @ingroup cpp_kodi_addon_pvr_Defs_EDLEntry
+/// @brief **Edit definition list (EDL) entry**\n
+/// Time places and type of related fields.
+///
+/// This used within @ref cpp_kodi_addon_pvr_EPGTag "EPG" and
+/// @ref cpp_kodi_addon_pvr_Recordings "recordings".
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry_Help
+///
+///@{
+class PVREDLEntry : public CStructHdl<PVREDLEntry, PVR_EDL_ENTRY>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVREDLEntry() { memset(m_cStructure, 0, sizeof(PVR_EDL_ENTRY)); }
+ PVREDLEntry(const PVREDLEntry& type) : CStructHdl(type) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Start time** | `int64_t` | @ref PVREDLEntry::SetStart "SetStart" | @ref PVREDLEntry::GetStart "GetStart" | *required to set*
+ /// | **End time** | `int64_t` | @ref PVREDLEntry::SetEnd "SetEnd" | @ref PVREDLEntry::GetEnd "GetEnd" | *required to set*
+ /// | **Type** | @ref PVR_EDL_TYPE | @ref PVREDLEntry::SetType "SetType" | @ref PVREDLEntry::GetType "GetType" | *required to set*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry
+ ///@{
+
+ /// @brief Start time in milliseconds.
+ void SetStart(int64_t start) { m_cStructure->start = start; }
+
+ /// @brief To get with @ref SetStart() changed values.
+ int64_t GetStart() const { return m_cStructure->start; }
+
+ /// @brief End time in milliseconds.
+ void SetEnd(int64_t end) { m_cStructure->end = end; }
+
+ /// @brief To get with @ref SetEnd() changed values.
+ int64_t GetEnd() const { return m_cStructure->end; }
+
+ /// @brief The with @ref PVR_EDL_TYPE used definition list type.
+ void SetType(PVR_EDL_TYPE type) { m_cStructure->type = type; }
+
+ /// @brief To get with @ref SetType() changed values.
+ PVR_EDL_TYPE GetType() const { return m_cStructure->type; }
+ ///@}
+
+private:
+ PVREDLEntry(const PVR_EDL_ENTRY* type) : CStructHdl(type) {}
+ PVREDLEntry(PVR_EDL_ENTRY* type) : CStructHdl(type) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EPG.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EPG.h
new file mode 100644
index 0000000..7603a75
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/EPG.h
@@ -0,0 +1,516 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 4 - PVR EPG
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_epg_PVREPGTag class PVREPGTag
+/// @ingroup cpp_kodi_addon_pvr_Defs_epg
+/// @brief **PVR add-on EPG data tag**\n
+/// Representation of an EPG event.
+///
+/// Herewith all EPG related data are saved in one class whereby the data can
+/// be exchanged with Kodi, or can also be used on the addon to save there.
+///
+/// See @ref cpp_kodi_addon_pvr_EPGTag "EPG methods" about usage.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_epg_PVREPGTag_Help
+///
+///@{
+class PVREPGTag : public CStructHdl<PVREPGTag, EPG_TAG>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVREPGTag()
+ {
+ memset(m_cStructure, 0, sizeof(EPG_TAG));
+ m_cStructure->iSeriesNumber = EPG_TAG_INVALID_SERIES_EPISODE;
+ m_cStructure->iEpisodeNumber = EPG_TAG_INVALID_SERIES_EPISODE;
+ m_cStructure->iEpisodePartNumber = EPG_TAG_INVALID_SERIES_EPISODE;
+ }
+ PVREPGTag(const PVREPGTag& epg)
+ : CStructHdl(epg),
+ m_title(epg.m_title),
+ m_plotOutline(epg.m_plotOutline),
+ m_plot(epg.m_plot),
+ m_originalTitle(epg.m_originalTitle),
+ m_cast(epg.m_cast),
+ m_director(epg.m_director),
+ m_writer(epg.m_writer),
+ m_IMDBNumber(epg.m_IMDBNumber),
+ m_episodeName(epg.m_episodeName),
+ m_iconPath(epg.m_iconPath),
+ m_seriesLink(epg.m_seriesLink),
+ m_genreDescription(epg.m_genreDescription),
+ m_parentalRatingCode(epg.m_parentalRatingCode),
+ m_firstAired(epg.m_firstAired)
+ {
+ }
+ /*! \endcond */
+
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_epg_PVREPGTag_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_PVREPGTag
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|---------
+ /// | **Unique broadcast id** | `unsigned int` | @ref PVREPGTag::SetUniqueBroadcastId "SetUniqueBroadcastId" | @ref PVREPGTag::GetUniqueBroadcastId "GetUniqueBroadcastId" | *required to set*
+ /// | **Unique channel id** | `unsigned int` | @ref PVREPGTag::SetUniqueChannelId "SetUniqueChannelId" | @ref PVREPGTag::GetUniqueChannelId "GetUniqueChannelId" | *required to set*
+ /// | **Title** | `std::string` | @ref PVREPGTag::SetTitle "SetTitle" | @ref PVREPGTag::GetTitle "GetTitle" | *required to set*
+ /// | **Start time** | `time_t` | @ref PVREPGTag::SetStartTime "SetStartTime" | @ref PVREPGTag::GetStartTime "GetStartTime" | *required to set*
+ /// | **End time** | `time_t` | @ref PVREPGTag::SetEndTime "SetEndTime" | @ref PVREPGTag::GetEndTime "GetEndTime" | *required to set*
+ /// | **Plot outline** | `std::string` | @ref PVREPGTag::SetPlotOutline "SetPlotOutline" | @ref PVREPGTag::GetPlotOutline "GetPlotOutline" | *optional*
+ /// | **Plot** | `std::string` | @ref PVREPGTag::SetPlot "SetPlot" | @ref PVREPGTag::GetPlot "GetPlot" | *optional*
+ /// | **Original title** | `std::string` | @ref PVREPGTag::SetOriginalTitle "SetOriginalTitle" | @ref PVREPGTag::GetOriginalTitle "GetOriginalTitle" | *optional*
+ /// | **Cast** | `std::string` | @ref PVREPGTag::SetCast "SetCast" | @ref PVREPGTag::GetCast "GetCast" | *optional*
+ /// | **Director** | `std::string` | @ref PVREPGTag::SetDirector "SetDirector" | @ref PVREPGTag::GetDirector "GetDirector" | *optional*
+ /// | **Writer** | `std::string` | @ref PVREPGTag::SetWriter "SetWriter" | @ref PVREPGTag::GetWriter "GetWriter" | *optional*
+ /// | **Year** | `int` | @ref PVREPGTag::SetYear "SetYear" | @ref PVREPGTag::GetYear "GetYear" | *optional*
+ /// | **IMDB number** | `std::string` | @ref PVREPGTag::SetIMDBNumber "SetIMDBNumber" | @ref PVREPGTag::GetIMDBNumber "GetIMDBNumber" | *optional*
+ /// | **Icon path** | `std::string` | @ref PVREPGTag::SetIconPath "SetIconPath" | @ref PVREPGTag::GetIconPath "GetIconPath" | *optional*
+ /// | **Genre type** | `int` | @ref PVREPGTag::SetGenreType "SetGenreType" | @ref PVREPGTag::GetGenreType "GetGenreType" | *optional*
+ /// | **Genre sub type** | `int` | @ref PVREPGTag::SetGenreSubType "SetGenreSubType" | @ref PVREPGTag::GetGenreSubType "GetGenreSubType" | *optional*
+ /// | **Genre description** | `std::string` | @ref PVREPGTag::SetGenreDescription "SetGenreDescription" | @ref PVREPGTag::GetGenreDescription "GetGenreDescription" | *optional*
+ /// | **First aired** | `time_t` | @ref PVREPGTag::SetFirstAired "SetFirstAired" | @ref PVREPGTag::GetFirstAired "GetFirstAired" | *optional*
+ /// | **Parental rating** | `int` | @ref PVREPGTag::SetParentalRating "SetParentalRating" | @ref PVREPGTag::GetParentalRating "GetParentalRating" | *optional*
+ /// | **Parental rating code** | `int` | @ref PVREPGTag::SetParentalRatingCode "SetParentalRatingCode" | @ref PVREPGTag::GetParentalRatingCode "GetParentalRatingCode" | *optional*
+ /// | **Star rating** | `int` | @ref PVREPGTag::SetStarRating "SetStarRating" | @ref PVREPGTag::GetStarRating "GetStarRating" | *optional*
+ /// | **Series number** | `int` | @ref PVREPGTag::SetSeriesNumber "SetSeriesNumber" | @ref PVREPGTag::GetSeriesNumber "GetSeriesNumber" | *optional*
+ /// | **Episode number** | `int` | @ref PVREPGTag::SetEpisodeNumber "SetEpisodeNumber" | @ref PVREPGTag::GetEpisodeNumber "GetEpisodeNumber" | *optional*
+ /// | **Episode part number** | `int` | @ref PVREPGTag::SetEpisodePartNumber "SetEpisodePartNumber" | @ref PVREPGTag::GetEpisodePartNumber "GetEpisodePartNumber" | *optional*
+ /// | **Episode name** | `std::string` | @ref PVREPGTag::SetEpisodeName "SetEpisodeName" | @ref PVREPGTag::GetEpisodeName "GetEpisodeName" | *optional*
+ /// | **Flags** | `unsigned int` | @ref PVREPGTag::SetFlags "SetFlags" | @ref PVREPGTag::GetFlags "GetFlags" | *optional*
+ /// | **Series link** | `std::string` | @ref PVREPGTag::SetSeriesLink "SetSeriesLink" | @ref PVREPGTag::GetSeriesLink "GetSeriesLink" | *optional*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_epg_PVREPGTag
+ ///@{
+
+ /// @brief **required**\n
+ /// Identifier for this event. Event uids must be unique for a channel. Valid uids must be greater than @ref EPG_TAG_INVALID_UID.
+ void SetUniqueBroadcastId(unsigned int uniqueBroadcastId)
+ {
+ m_cStructure->iUniqueBroadcastId = uniqueBroadcastId;
+ }
+
+ /// @brief To get with @ref SetUniqueBroadcastId changed values.
+ unsigned int GetUniqueBroadcastId() const { return m_cStructure->iUniqueBroadcastId; }
+
+ /// @brief **required**\n
+ /// Unique identifier of the channel this event belongs to.
+ void SetUniqueChannelId(unsigned int uniqueChannelId)
+ {
+ m_cStructure->iUniqueChannelId = uniqueChannelId;
+ }
+
+ /// @brief To get with @ref SetUniqueChannelId changed values
+ unsigned int GetUniqueChannelId() const { return m_cStructure->iUniqueChannelId; }
+
+ /// @brief **required**\n
+ /// This event's title.
+ void SetTitle(const std::string& title) { m_title = title; }
+
+ /// @brief To get with @ref SetTitle changed values.
+ std::string GetTitle() const { return m_title; }
+
+ /// @brief **required**\n
+ /// Start time in UTC.
+ ///
+ /// Seconds elapsed since 00:00 hours, Jan 1, 1970 UTC.
+ void SetStartTime(time_t startTime) { m_cStructure->startTime = startTime; }
+
+ /// @brief To get with @ref SetStartTime changed values.
+ time_t GetStartTime() const { return m_cStructure->startTime; }
+
+ /// @brief **required**\n
+ /// End time in UTC.
+ ///
+ /// Seconds elapsed since 00:00 hours, Jan 1, 1970 UTC.
+ void SetEndTime(time_t endTime) { m_cStructure->endTime = endTime; }
+
+ /// @brief To get with @ref SetEndTime changed values.
+ time_t GetEndTime() const { return m_cStructure->endTime; }
+
+ /// @brief **optional**\n
+ /// Plot outline name.
+ void SetPlotOutline(const std::string& plotOutline) { m_plotOutline = plotOutline; }
+
+ /// @brief To get with @ref SetPlotOutline changed values.
+ std::string GetPlotOutline() const { return m_plotOutline; }
+
+ /// @brief **optional**\n
+ /// Plot name.
+ void SetPlot(const std::string& plot) { m_plot = plot; }
+
+ /// @brief To get with @ref GetPlot changed values.
+ std::string GetPlot() const { return m_plot; }
+
+ /// @brief **optional**\n
+ /// Original title.
+ void SetOriginalTitle(const std::string& originalTitle) { m_originalTitle = originalTitle; }
+
+ /// @brief To get with @ref SetOriginalTitle changed values
+ std::string GetOriginalTitle() const { return m_originalTitle; }
+
+ /// @brief **optional**\n
+ /// Cast name(s).
+ ///
+ /// @note Use @ref EPG_STRING_TOKEN_SEPARATOR to separate different persons.
+ void SetCast(const std::string& cast) { m_cast = cast; }
+
+ /// @brief To get with @ref SetCast changed values
+ std::string GetCast() const { return m_cast; }
+
+ /// @brief **optional**\n
+ /// Director name(s).
+ ///
+ /// @note Use @ref EPG_STRING_TOKEN_SEPARATOR to separate different persons.
+ void SetDirector(const std::string& director) { m_director = director; }
+
+ /// @brief To get with @ref SetDirector changed values.
+ std::string GetDirector() const { return m_director; }
+
+ /// @brief **optional**\n
+ /// Writer name(s).
+ ///
+ /// @note Use @ref EPG_STRING_TOKEN_SEPARATOR to separate different persons.
+ void SetWriter(const std::string& writer) { m_writer = writer; }
+
+ /// @brief To get with @ref SetDirector changed values
+ std::string GetWriter() const { return m_writer; }
+
+ /// @brief **optional**\n
+ /// Year.
+ void SetYear(int year) { m_cStructure->iYear = year; }
+
+ /// @brief To get with @ref SetYear changed values.
+ int GetYear() const { return m_cStructure->iYear; }
+
+ /// @brief **optional**\n
+ /// [IMDB](https://en.wikipedia.org/wiki/IMDb) identification number.
+ void SetIMDBNumber(const std::string& IMDBNumber) { m_IMDBNumber = IMDBNumber; }
+
+ /// @brief To get with @ref SetIMDBNumber changed values.
+ std::string GetIMDBNumber() const { return m_IMDBNumber; }
+
+ /// @brief **optional**\n
+ /// Icon path.
+ void SetIconPath(const std::string& iconPath) { m_iconPath = iconPath; }
+
+ /// @brief To get with @ref SetIconPath changed values.
+ std::string GetIconPath() const { return m_iconPath; }
+
+ /// @brief **optional**\n
+ /// Genre type.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails EPG_EVENT_CONTENTMASK
+ ///
+ /// Use @ref EPG_GENRE_USE_STRING if type becomes given by @ref SetGenreDescription.
+ ///
+ /// @note If confirmed that backend brings the types in [ETSI EN 300 468](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf)
+ /// conform values, can be @ref EPG_EVENT_CONTENTMASK ignored and to set here
+ /// with backend value.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example 1:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVREPGTag tag;
+ /// tag.SetGenreType(EPG_EVENT_CONTENTMASK_MOVIEDRAMA);
+ /// ~~~~~~~~~~~~~
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example 2** (in case of other, not ETSI EN 300 468 conform genre types):
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVREPGTag tag;
+ /// tag.SetGenreType(EPG_GENRE_USE_STRING);
+ /// tag.SetGenreDescription("My special genre name"); // Should use (if possible) kodi::GetLocalizedString(...) to have match user language.
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetGenreType(int genreType) { m_cStructure->iGenreType = genreType; }
+
+ /// @brief To get with @ref SetGenreType changed values
+ int GetGenreType() const { return m_cStructure->iGenreType; }
+
+ /// @brief **optional**\n
+ /// Genre sub type.
+ ///
+ /// @copydetails EPG_EVENT_CONTENTMASK
+ ///
+ /// Subtypes groups related to set by @ref SetGenreType:
+ /// | Main genre type | List with available sub genre types
+ /// |-----------------|-----------------------------------------
+ /// | @ref EPG_EVENT_CONTENTMASK_UNDEFINED | Nothing, should be 0
+ /// | @ref EPG_EVENT_CONTENTMASK_MOVIEDRAMA | @ref EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA
+ /// | @ref EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS | @ref EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS
+ /// | @ref EPG_EVENT_CONTENTMASK_SHOW | @ref EPG_EVENT_CONTENTSUBMASK_SHOW
+ /// | @ref EPG_EVENT_CONTENTMASK_SPORTS | @ref EPG_EVENT_CONTENTSUBMASK_SPORTS
+ /// | @ref EPG_EVENT_CONTENTMASK_CHILDRENYOUTH | @ref EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH
+ /// | @ref EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE | @ref EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE
+ /// | @ref EPG_EVENT_CONTENTMASK_ARTSCULTURE | @ref EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE
+ /// | @ref EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS | @ref EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS
+ /// | @ref EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE | @ref EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE
+ /// | @ref EPG_EVENT_CONTENTMASK_LEISUREHOBBIES | @ref EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES
+ /// | @ref EPG_EVENT_CONTENTMASK_SPECIAL | @ref EPG_EVENT_CONTENTSUBMASK_SPECIAL
+ /// | @ref EPG_EVENT_CONTENTMASK_USERDEFINED | Can be defined by you
+ /// | @ref EPG_GENRE_USE_STRING | **Kodi's own value**, which declares that the type with @ref SetGenreDescription is given.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVREPGTag tag;
+ /// tag.SetGenreType(EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE);
+ /// tag.SetGenreSubType(EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_JAZZ);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetGenreSubType(int genreSubType) { m_cStructure->iGenreSubType = genreSubType; }
+
+ /// @brief To get with @ref SetGenreSubType changed values.
+ int GetGenreSubType() const { return m_cStructure->iGenreSubType; }
+
+ /// @brief **optional**\n genre. Will be used only when genreType == @ref EPG_GENRE_USE_STRING
+ /// or genreSubType == @ref EPG_GENRE_USE_STRING.
+ ///
+ /// Use @ref EPG_STRING_TOKEN_SEPARATOR to separate different genres.
+ ///
+ /// In case of other, not [ETSI EN 300 468](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf)
+ /// conform genre types or something special.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVREPGTag tag;
+ /// tag.SetGenreType(EPG_GENRE_USE_STRING);
+ /// tag.SetGenreDescription("Action" + EPG_STRING_TOKEN_SEPARATOR + "Thriller");
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetGenreDescription(const std::string& genreDescription)
+ {
+ m_genreDescription = genreDescription;
+ }
+
+ /// @brief To get with @ref SetGenreDescription changed values.
+ std::string GetGenreDescription() const { return m_genreDescription; }
+
+ /// @brief **optional**\n
+ /// First aired in UTC.
+ void SetFirstAired(const std::string& firstAired) { m_firstAired = firstAired; }
+
+ /// @brief To get with @ref SetFirstAired changed values.
+ std::string GetFirstAired() const { return m_firstAired; }
+
+ /// @brief **optional**\n
+ /// Parental rating.
+ void SetParentalRating(int parentalRating) { m_cStructure->iParentalRating = parentalRating; }
+
+ /// @brief To get with @ref SetParentalRatinge changed values.
+ int GetParentalRating() const { return m_cStructure->iParentalRating; }
+
+ /// @brief **required**\n
+ /// This event's parental rating code.
+ void SetParentalRatingCode(const std::string& parentalRatingCode)
+ {
+ m_parentalRatingCode = parentalRatingCode;
+ }
+
+ /// @brief To get with @ref SetParentalRatingCode changed values.
+ std::string GetParentalRatingCode() const { return m_parentalRatingCode; }
+
+ /// @brief **optional**\n
+ /// Star rating.
+ void SetStarRating(int starRating) { m_cStructure->iStarRating = starRating; }
+
+ /// @brief To get with @ref SetStarRating changed values.
+ int GetStarRating() const { return m_cStructure->iStarRating; }
+
+ /// @brief **optional**\n
+ /// Series number.
+ void SetSeriesNumber(int seriesNumber) { m_cStructure->iSeriesNumber = seriesNumber; }
+
+ /// @brief To get with @ref SetSeriesNumber changed values.
+ int GetSeriesNumber() const { return m_cStructure->iSeriesNumber; }
+
+ /// @brief **optional**\n
+ /// Episode number.
+ void SetEpisodeNumber(int episodeNumber) { m_cStructure->iEpisodeNumber = episodeNumber; }
+
+ /// @brief To get with @ref SetEpisodeNumber changed values.
+ int GetEpisodeNumber() const { return m_cStructure->iEpisodeNumber; }
+
+ /// @brief **optional**\n
+ /// Episode part number.
+ void SetEpisodePartNumber(int episodePartNumber)
+ {
+ m_cStructure->iEpisodePartNumber = episodePartNumber;
+ }
+
+ /// @brief To get with @ref SetEpisodePartNumber changed values.
+ int GetEpisodePartNumber() const { return m_cStructure->iEpisodePartNumber; }
+
+ /// @brief **optional**\n
+ /// Episode name.
+ void SetEpisodeName(const std::string& episodeName) { m_episodeName = episodeName; }
+
+ /// @brief To get with @ref SetEpisodeName changed values.
+ std::string GetEpisodeName() const { return m_episodeName; }
+
+ /// @brief **optional**\n
+ /// Bit field of independent flags associated with the EPG entry.
+ ///
+ /// See @ref cpp_kodi_addon_pvr_Defs_epg_EPG_TAG_FLAG for available bit flags.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_epg_EPG_TAG_FLAG
+ ///
+ void SetFlags(unsigned int flags) { m_cStructure->iFlags = flags; }
+
+ /// @brief To get with @ref SetFlags changed values.
+ unsigned int GetFlags() const { return m_cStructure->iFlags; }
+
+ /// @brief **optional**\n
+ /// Series link for this event.
+ void SetSeriesLink(const std::string& seriesLink) { m_seriesLink = seriesLink; }
+
+ /// @brief To get with @ref SetSeriesLink changed values.
+ std::string GetSeriesLink() const { return m_seriesLink; }
+
+ ///@}
+
+ // Internal used, as this have own memory for strings and to translate them to "C"
+ EPG_TAG* GetTag() const
+ {
+ m_cStructure->strTitle = m_title.c_str();
+ m_cStructure->strPlotOutline = m_plotOutline.c_str();
+ m_cStructure->strPlot = m_plot.c_str();
+ m_cStructure->strOriginalTitle = m_originalTitle.c_str();
+ m_cStructure->strCast = m_cast.c_str();
+ m_cStructure->strDirector = m_director.c_str();
+ m_cStructure->strWriter = m_writer.c_str();
+ m_cStructure->strIMDBNumber = m_IMDBNumber.c_str();
+ m_cStructure->strIconPath = m_iconPath.c_str();
+ m_cStructure->strGenreDescription = m_genreDescription.c_str();
+ m_cStructure->strParentalRatingCode = m_parentalRatingCode.c_str();
+ m_cStructure->strEpisodeName = m_episodeName.c_str();
+ m_cStructure->strSeriesLink = m_seriesLink.c_str();
+ m_cStructure->strFirstAired = m_firstAired.c_str();
+
+ return m_cStructure;
+ }
+
+private:
+ PVREPGTag(const EPG_TAG* epg) : CStructHdl(epg) { SetData(epg); }
+ PVREPGTag(EPG_TAG* epg) : CStructHdl(epg) { SetData(epg); }
+
+ const PVREPGTag& operator=(const PVREPGTag& right);
+ const PVREPGTag& operator=(const EPG_TAG& right);
+ operator EPG_TAG*();
+
+ std::string m_title;
+ std::string m_plotOutline;
+ std::string m_plot;
+ std::string m_originalTitle;
+ std::string m_cast;
+ std::string m_director;
+ std::string m_writer;
+ std::string m_IMDBNumber;
+ std::string m_episodeName;
+ std::string m_iconPath;
+ std::string m_seriesLink;
+ std::string m_genreDescription;
+ std::string m_parentalRatingCode;
+ std::string m_firstAired;
+
+ void SetData(const EPG_TAG* tag)
+ {
+ m_title = tag->strTitle == nullptr ? "" : tag->strTitle;
+ m_plotOutline = tag->strPlotOutline == nullptr ? "" : tag->strPlotOutline;
+ m_plot = tag->strPlot == nullptr ? "" : tag->strPlot;
+ m_originalTitle = tag->strOriginalTitle == nullptr ? "" : tag->strOriginalTitle;
+ m_cast = tag->strCast == nullptr ? "" : tag->strCast;
+ m_director = tag->strDirector == nullptr ? "" : tag->strDirector;
+ m_writer = tag->strWriter == nullptr ? "" : tag->strWriter;
+ m_IMDBNumber = tag->strIMDBNumber == nullptr ? "" : tag->strIMDBNumber;
+ m_iconPath = tag->strIconPath == nullptr ? "" : tag->strIconPath;
+ m_genreDescription = tag->strGenreDescription == nullptr ? "" : tag->strGenreDescription;
+ m_parentalRatingCode = tag->strParentalRatingCode == nullptr ? "" : tag->strParentalRatingCode;
+ m_episodeName = tag->strEpisodeName == nullptr ? "" : tag->strEpisodeName;
+ m_seriesLink = tag->strSeriesLink == nullptr ? "" : tag->strSeriesLink;
+ m_firstAired = tag->strFirstAired == nullptr ? "" : tag->strFirstAired;
+ }
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_epg_PVREPGTagsResultSet class PVREPGTagsResultSet
+/// @ingroup cpp_kodi_addon_pvr_Defs_epg_PVREPGTag
+/// @brief **PVR add-on EPG entry transfer class**\n
+/// To transfer the content of @ref kodi::addon::CInstancePVRClient::GetEPGForChannel().
+///
+/// @note This becomes only be used on addon call above, not usable outside on
+/// addon itself.
+///@{
+class PVREPGTagsResultSet
+{
+public:
+ /*! \cond PRIVATE */
+ PVREPGTagsResultSet() = delete;
+ PVREPGTagsResultSet(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ : m_instance(instance), m_handle(handle)
+ {
+ }
+ /*! \endcond */
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_epg_PVREPGTagsResultSet
+ ///@{
+
+ /// @brief To add and give content from addon to Kodi on related call.
+ ///
+ /// @param[in] tag The to transferred data.
+ void Add(const kodi::addon::PVREPGTag& tag)
+ {
+ m_instance->toKodi->TransferEpgEntry(m_instance->toKodi->kodiInstance, m_handle, tag.GetTag());
+ }
+
+ ///@}
+
+private:
+ const AddonInstance_PVR* m_instance = nullptr;
+ const PVR_HANDLE m_handle;
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/General.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/General.h
new file mode 100644
index 0000000..758feed
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/General.h
@@ -0,0 +1,536 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr/pvr_general.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 1 - General PVR
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_PVRTypeIntValue class PVRTypeIntValue
+/// @ingroup cpp_kodi_addon_pvr_Defs_General
+/// @brief **PVR add-on type value**\n
+/// Representation of a <b>`<int, std::string>`</b> event related value.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help
+///
+///@{
+class PVRTypeIntValue : public CStructHdl<PVRTypeIntValue, PVR_ATTRIBUTE_INT_VALUE>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRTypeIntValue(const PVRTypeIntValue& data) : CStructHdl(data) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_PVRTypeIntValue
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_PVRTypeIntValue :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Value** | `int` | @ref PVRTypeIntValue::SetValue "SetValue" | @ref PVRTypeIntValue::GetValue "GetValue"
+ /// | **Description** | `std::string` | @ref PVRTypeIntValue::SetDescription "SetDescription" | @ref PVRTypeIntValue::GetDescription "GetDescription"
+ ///
+ /// @remark Further can there be used his class constructor to set values.
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_PVRTypeIntValue
+ ///@{
+
+ /// @brief Default class constructor.
+ ///
+ /// @note Values must be set afterwards.
+ PVRTypeIntValue() = default;
+
+ /// @brief Class constructor with integrated value set.
+ ///
+ /// @param[in] value Type identification value
+ /// @param[in] description Type description text
+ PVRTypeIntValue(int value, const std::string& description)
+ {
+ SetValue(value);
+ SetDescription(description);
+ }
+
+ /// @brief To set with the identification value.
+ void SetValue(int value) { m_cStructure->iValue = value; }
+
+ /// @brief To get with the identification value.
+ int GetValue() const { return m_cStructure->iValue; }
+
+ /// @brief To set with the description text of the value.
+ void SetDescription(const std::string& description)
+ {
+ strncpy(m_cStructure->strDescription, description.c_str(),
+ sizeof(m_cStructure->strDescription) - 1);
+ }
+
+ /// @brief To get with the description text of the value.
+ std::string GetDescription() const { return m_cStructure->strDescription; }
+ ///@}
+
+private:
+ PVRTypeIntValue(const PVR_ATTRIBUTE_INT_VALUE* data) : CStructHdl(data) {}
+ PVRTypeIntValue(PVR_ATTRIBUTE_INT_VALUE* data) : CStructHdl(data) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_PVRCapabilities class PVRCapabilities
+/// @ingroup cpp_kodi_addon_pvr_Defs_General
+/// @brief **PVR add-on capabilities**\n
+/// This class is needed to tell Kodi which options are supported on the addon.
+///
+/// If a capability is set to **true**, then the corresponding methods from
+/// @ref cpp_kodi_addon_pvr "kodi::addon::CInstancePVRClient" need to be
+/// implemented.
+///
+/// As default them all set to **false**.
+///
+/// Used on @ref kodi::addon::CInstancePVRClient::GetCapabilities().
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_PVRCapabilities_Help
+///
+///@{
+class PVRCapabilities
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ explicit PVRCapabilities() = delete;
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_PVRCapabilities_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_PVRCapabilities
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_PVRCapabilities :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Supports EPG** | `boolean` | @ref PVRCapabilities::SetSupportsEPG "SetSupportsEPG" | @ref PVRCapabilities::GetSupportsEPG "GetSupportsEPG"
+ /// | **Supports EPG EDL** | `boolean` | @ref PVRCapabilities::SetSupportsEPGEdl "SetSupportsEPGEdl" | @ref PVRCapabilities::GetSupportsEPGEdl "GetSupportsEPGEdl"
+ /// | **Supports TV** | `boolean` | @ref PVRCapabilities::SetSupportsTV "SetSupportsTV" | @ref PVRCapabilities::GetSupportsTV "GetSupportsTV"
+ /// | **Supports radio** | `boolean` | @ref PVRCapabilities::SetSupportsRadio "SetSupportsRadio" | @ref PVRCapabilities::GetSupportsRadio "GetSupportsRadio"
+ /// | **Supports recordings** | `boolean` | @ref PVRCapabilities::SetSupportsRecordings "SetSupportsRecordings" | @ref PVRCapabilities::GetSupportsRecordings "GetSupportsRecordings"
+ /// | **Supports recordings undelete** | `boolean` | @ref PVRCapabilities::SetSupportsRecordingsUndelete "SetSupportsRecordingsUndelete" | @ref PVRCapabilities::GetSupportsRecordingsUndelete "SetSupportsRecordingsUndelete"
+ /// | **Supports timers** | `boolean` | @ref PVRCapabilities::SetSupportsTimers "SetSupportsTimers" | @ref PVRCapabilities::GetSupportsTimers "GetSupportsTimers"
+ /// | **Supports providers** | `boolean` | @ref PVRCapabilities::SetSupportsProviders "SetSupportsProviders" | @ref PVRCapabilities::GetSupportsProviders "GetSupportsProviders"
+ /// | **Supports channel groups** | `boolean` | @ref PVRCapabilities::SetSupportsChannelGroups "SetSupportsChannelGroups" | @ref PVRCapabilities::GetSupportsChannelGroups "GetSupportsChannelGroups"
+ /// | **Supports channel scan** | `boolean` | @ref PVRCapabilities::SetSupportsChannelScan "SetSupportsChannelScan" | @ref PVRCapabilities::GetSupportsChannelScan "GetSupportsChannelScan"
+ /// | **Supports channel settings** | `boolean` | @ref PVRCapabilities::SetSupportsChannelSettings "SetSupportsChannelSettings" | @ref PVRCapabilities::GetSupportsChannelSettings "GetSupportsChannelSettings"
+ /// | **Handles input stream** | `boolean` | @ref PVRCapabilities::SetHandlesInputStream "SetHandlesInputStream" | @ref PVRCapabilities::GetHandlesInputStream "GetHandlesInputStream"
+ /// | **Handles demuxing** | `boolean` | @ref PVRCapabilities::SetHandlesDemuxing "SetHandlesDemuxing" | @ref PVRCapabilities::GetHandlesDemuxing "GetHandlesDemuxing"
+ /// | **Supports recording play count** | `boolean` | @ref PVRCapabilities::SetSupportsRecordingPlayCount "SetSupportsRecordingPlayCount" | @ref PVRCapabilities::GetSupportsRecordingPlayCount "GetSupportsRecordingPlayCount"
+ /// | **Supports last played position** | `boolean` | @ref PVRCapabilities::SetSupportsLastPlayedPosition "SetSupportsLastPlayedPosition" | @ref PVRCapabilities::GetSupportsLastPlayedPosition "GetSupportsLastPlayedPosition"
+ /// | **Supports recording EDL** | `boolean` | @ref PVRCapabilities::SetSupportsRecordingEdl "SetSupportsRecordingEdl" | @ref PVRCapabilities::GetSupportsRecordingEdl "GetSupportsRecordingEdl"
+ /// | **Supports recordings rename** | `boolean` | @ref PVRCapabilities::SetSupportsRecordingsRename "SetSupportsRecordingsRename" | @ref PVRCapabilities::GetSupportsRecordingsRename "GetSupportsRecordingsRename"
+ /// | **Supports recordings lifetime change** | `boolean` | @ref PVRCapabilities::SetSupportsRecordingsLifetimeChange "SetSupportsRecordingsLifetimeChange" | @ref PVRCapabilities::GetSupportsRecordingsLifetimeChange "GetSupportsRecordingsLifetimeChange"
+ /// | **Supports descramble info** | `boolean` | @ref PVRCapabilities::SetSupportsDescrambleInfo "SetSupportsDescrambleInfo" | @ref PVRCapabilities::GetSupportsDescrambleInfo "GetSupportsDescrambleInfo"
+ /// | **Supports async EPG transfer** | `boolean` | @ref PVRCapabilities::SetSupportsAsyncEPGTransfer "SetSupportsAsyncEPGTransfer" | @ref PVRCapabilities::GetSupportsAsyncEPGTransfer "GetSupportsAsyncEPGTransfer"
+ /// | **Supports recording size** | `boolean` | @ref PVRCapabilities::SetSupportsRecordingSize "SetSupportsRecordingSize" | @ref PVRCapabilities::GetSupportsRecordingSize "GetSupportsRecordingSize"
+ /// | **Supports recordings delete** | `boolean` | @ref PVRCapabilities::SetSupportsRecordingsDelete "SetSupportsRecordingsDelete" | @ref PVRCapabilities::GetSupportsRecordingsDelete "SetSupportsRecordingsDelete"
+ /// | **Recordings lifetime values** | @ref cpp_kodi_addon_pvr_Defs_PVRTypeIntValue "PVRTypeIntValue" | @ref PVRCapabilities::SetRecordingsLifetimeValues "SetRecordingsLifetimeValues" | @ref PVRCapabilities::GetRecordingsLifetimeValues "GetRecordingsLifetimeValues"
+ ///
+ /// @warning This class can not be used outside of @ref kodi::addon::CInstancePVRClient::GetCapabilities()
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_PVRCapabilities
+ ///@{
+
+ /// @brief Set **true** if the add-on provides EPG information.
+ void SetSupportsEPG(bool supportsEPG) { m_capabilities->bSupportsEPG = supportsEPG; }
+
+ /// @brief To get with @ref SetSupportsEPG changed values.
+ bool GetSupportsEPG() const { return m_capabilities->bSupportsEPG; }
+
+ /// @brief Set **true** if the backend supports retrieving an edit decision
+ /// list for an EPG tag.
+ void SetSupportsEPGEdl(bool supportsEPGEdl) { m_capabilities->bSupportsEPGEdl = supportsEPGEdl; }
+
+ /// @brief To get with @ref SetSupportsEPGEdl changed values.
+ bool GetSupportsEPGEdl() const { return m_capabilities->bSupportsEPGEdl; }
+
+ /// @brief Set **true** if this add-on provides TV channels.
+ void SetSupportsTV(bool supportsTV) { m_capabilities->bSupportsTV = supportsTV; }
+
+ /// @brief To get with @ref SetSupportsTV changed values.
+ bool GetSupportsTV() const { return m_capabilities->bSupportsTV; }
+
+ /// @brief Set **true** if this add-on provides TV channels.
+ void SetSupportsRadio(bool supportsRadio) { m_capabilities->bSupportsRadio = supportsRadio; }
+
+ /// @brief To get with @ref SetSupportsRadio changed values.
+ bool GetSupportsRadio() const { return m_capabilities->bSupportsRadio; }
+
+ /// @brief **true** if this add-on supports playback of recordings stored on
+ /// the backend.
+ void SetSupportsRecordings(bool supportsRecordings)
+ {
+ m_capabilities->bSupportsRecordings = supportsRecordings;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordings changed values.
+ bool GetSupportsRecordings() const { return m_capabilities->bSupportsRecordings; }
+
+ /// @brief Set **true** if this add-on supports undelete of recordings stored
+ /// on the backend.
+ void SetSupportsRecordingsUndelete(bool supportsRecordingsUndelete)
+ {
+ m_capabilities->bSupportsRecordingsUndelete = supportsRecordingsUndelete;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordings changed values.
+ bool GetSupportsRecordingsUndelete() const { return m_capabilities->bSupportsRecordingsUndelete; }
+
+ /// @brief Set **true** if this add-on supports the creation and editing of
+ /// timers.
+ void SetSupportsTimers(bool supportsTimers) { m_capabilities->bSupportsTimers = supportsTimers; }
+
+ /// @brief To get with @ref SetSupportsTimers changed values.
+ bool GetSupportsTimers() const { return m_capabilities->bSupportsTimers; }
+
+ /// @brief Set **true** if this add-on supports providers.
+ ///
+ /// It uses the following functions:
+ /// - @ref kodi::addon::CInstancePVRClient::GetProvidersAmount()
+ /// - @ref kodi::addon::CInstancePVRClient::GetProviders()
+ void SetSupportsProviders(bool supportsProviders)
+ {
+ m_capabilities->bSupportsProviders = supportsProviders;
+ }
+
+ /// @brief To get with @ref SetSupportsProviders changed values.
+ bool GetSupportsProviders() const { return m_capabilities->bSupportsProviders; }
+
+ /// @brief Set **true** if this add-on supports channel groups.
+ ///
+ /// It use the following functions:
+ /// - @ref kodi::addon::CInstancePVRClient::GetChannelGroupsAmount()
+ /// - @ref kodi::addon::CInstancePVRClient::GetChannelGroups()
+ /// - @ref kodi::addon::CInstancePVRClient::GetChannelGroupMembers()
+ void SetSupportsChannelGroups(bool supportsChannelGroups)
+ {
+ m_capabilities->bSupportsChannelGroups = supportsChannelGroups;
+ }
+
+ /// @brief To get with @ref SetSupportsChannelGroups changed values.
+ bool GetSupportsChannelGroups() const { return m_capabilities->bSupportsChannelGroups; }
+
+ /// @brief Set **true** if this add-on support scanning for new channels on
+ /// the backend.
+ ///
+ /// It use the following function:
+ /// - @ref kodi::addon::CInstancePVRClient::OpenDialogChannelScan()
+ void SetSupportsChannelScan(bool supportsChannelScan)
+ {
+ m_capabilities->bSupportsChannelScan = supportsChannelScan;
+ }
+
+ /// @brief To get with @ref SetSupportsChannelScan changed values.
+ bool GetSupportsChannelScan() const { return m_capabilities->bSupportsChannelScan; }
+
+ /// @brief Set **true** if this add-on supports channel edit.
+ ///
+ /// It use the following functions:
+ /// - @ref kodi::addon::CInstancePVRClient::DeleteChannel()
+ /// - @ref kodi::addon::CInstancePVRClient::RenameChannel()
+ /// - @ref kodi::addon::CInstancePVRClient::OpenDialogChannelSettings()
+ /// - @ref kodi::addon::CInstancePVRClient::OpenDialogChannelAdd()
+ void SetSupportsChannelSettings(bool supportsChannelSettings)
+ {
+ m_capabilities->bSupportsChannelSettings = supportsChannelSettings;
+ }
+
+ /// @brief To get with @ref SetSupportsChannelSettings changed values.
+ bool GetSupportsChannelSettings() const { return m_capabilities->bSupportsChannelSettings; }
+
+ /// @brief Set **true** if this add-on provides an input stream. false if Kodi
+ /// handles the stream.
+ void SetHandlesInputStream(bool handlesInputStream)
+ {
+ m_capabilities->bHandlesInputStream = handlesInputStream;
+ }
+
+ /// @brief To get with @ref SetHandlesInputStream changed values.
+ bool GetHandlesInputStream() const { return m_capabilities->bHandlesInputStream; }
+
+ /// @brief Set **true** if this add-on demultiplexes packets.
+ void SetHandlesDemuxing(bool handlesDemuxing)
+ {
+ m_capabilities->bHandlesDemuxing = handlesDemuxing;
+ }
+
+ /// @brief To get with @ref SetHandlesDemuxing changed values.
+ bool GetHandlesDemuxing() const { return m_capabilities->bHandlesDemuxing; }
+
+ /// @brief Set **true** if the backend supports play count for recordings.
+ void SetSupportsRecordingPlayCount(bool supportsRecordingPlayCount)
+ {
+ m_capabilities->bSupportsRecordingPlayCount = supportsRecordingPlayCount;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordingPlayCount changed values.
+ bool GetSupportsRecordingPlayCount() const { return m_capabilities->bSupportsRecordingPlayCount; }
+
+ /// @brief Set **true** if the backend supports store/retrieve of last played
+ /// position for recordings.
+ void SetSupportsLastPlayedPosition(bool supportsLastPlayedPosition)
+ {
+ m_capabilities->bSupportsLastPlayedPosition = supportsLastPlayedPosition;
+ }
+
+ /// @brief To get with @ref SetSupportsLastPlayedPosition changed values.
+ bool GetSupportsLastPlayedPosition() const { return m_capabilities->bSupportsLastPlayedPosition; }
+
+ /// @brief Set **true** if the backend supports retrieving an edit decision
+ /// list for recordings.
+ void SetSupportsRecordingEdl(bool supportsRecordingEdl)
+ {
+ m_capabilities->bSupportsRecordingEdl = supportsRecordingEdl;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordingEdl changed values.
+ bool GetSupportsRecordingEdl() const { return m_capabilities->bSupportsRecordingEdl; }
+
+ /// @brief Set **true** if the backend supports renaming recordings.
+ void SetSupportsRecordingsRename(bool supportsRecordingsRename)
+ {
+ m_capabilities->bSupportsRecordingsRename = supportsRecordingsRename;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordingsRename changed values.
+ bool GetSupportsRecordingsRename() const { return m_capabilities->bSupportsRecordingsRename; }
+
+ /// @brief Set **true** if the backend supports changing lifetime for
+ /// recordings.
+ void SetSupportsRecordingsLifetimeChange(bool supportsRecordingsLifetimeChange)
+ {
+ m_capabilities->bSupportsRecordingsLifetimeChange = supportsRecordingsLifetimeChange;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordingsLifetimeChange changed
+ /// values.
+ bool GetSupportsRecordingsLifetimeChange() const
+ {
+ return m_capabilities->bSupportsRecordingsLifetimeChange;
+ }
+
+ /// @brief Set **true** if the backend supports descramble information for
+ /// playing channels.
+ void SetSupportsDescrambleInfo(bool supportsDescrambleInfo)
+ {
+ m_capabilities->bSupportsDescrambleInfo = supportsDescrambleInfo;
+ }
+
+ /// @brief To get with @ref SetSupportsDescrambleInfo changed values.
+ bool GetSupportsDescrambleInfo() const { return m_capabilities->bSupportsDescrambleInfo; }
+
+ /// @brief Set **true** if this addon-on supports asynchronous transfer of epg
+ /// events to Kodi using the callback function
+ /// @ref kodi::addon::CInstancePVRClient::EpgEventStateChange().
+ void SetSupportsAsyncEPGTransfer(bool supportsAsyncEPGTransfer)
+ {
+ m_capabilities->bSupportsAsyncEPGTransfer = supportsAsyncEPGTransfer;
+ }
+
+ /// @brief To get with @ref SetSupportsAsyncEPGTransfer changed values.
+ bool GetSupportsAsyncEPGTransfer() const { return m_capabilities->bSupportsAsyncEPGTransfer; }
+
+ /// @brief Set **true** if this addon-on supports retrieving size of recordings.
+ void SetSupportsRecordingSize(bool supportsRecordingSize)
+ {
+ m_capabilities->bSupportsRecordingSize = supportsRecordingSize;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordingSize changed values.
+ bool GetSupportsRecordingSize() const { return m_capabilities->bSupportsRecordingSize; }
+
+ /// @brief Set **true** if this add-on supports delete of recordings stored
+ /// on the backend.
+ void SetSupportsRecordingsDelete(bool supportsRecordingsDelete)
+ {
+ m_capabilities->bSupportsRecordingsDelete = supportsRecordingsDelete;
+ }
+
+ /// @brief To get with @ref SetSupportsRecordingsDelete changed values.
+ bool GetSupportsRecordingsDelete() const { return m_capabilities->bSupportsRecordingsDelete; }
+
+ /// @brief **optional**\n
+ /// Set array containing the possible values for @ref PVRRecording::SetLifetime().
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help
+ void SetRecordingsLifetimeValues(
+ const std::vector<PVRTypeIntValue>& recordingsLifetimeValues)
+ {
+ m_capabilities->iRecordingsLifetimesSize = 0;
+ for (unsigned int i = 0; i < recordingsLifetimeValues.size() &&
+ i < sizeof(m_capabilities->recordingsLifetimeValues);
+ ++i)
+ {
+ m_capabilities->recordingsLifetimeValues[i].iValue =
+ recordingsLifetimeValues[i].GetCStructure()->iValue;
+ strncpy(m_capabilities->recordingsLifetimeValues[i].strDescription,
+ recordingsLifetimeValues[i].GetCStructure()->strDescription,
+ sizeof(m_capabilities->recordingsLifetimeValues[i].strDescription) - 1);
+ ++m_capabilities->iRecordingsLifetimesSize;
+ }
+ }
+
+ /// @brief To get with @ref SetRecordingsLifetimeValues changed values.
+ std::vector<PVRTypeIntValue> GetRecordingsLifetimeValues() const
+ {
+ std::vector<PVRTypeIntValue> recordingsLifetimeValues;
+ for (unsigned int i = 0; i < m_capabilities->iRecordingsLifetimesSize; ++i)
+ recordingsLifetimeValues.emplace_back(
+ m_capabilities->recordingsLifetimeValues[i].iValue,
+ m_capabilities->recordingsLifetimeValues[i].strDescription);
+ return recordingsLifetimeValues;
+ }
+ ///@}
+
+private:
+ PVRCapabilities(PVR_ADDON_CAPABILITIES* capabilities) : m_capabilities(capabilities) {}
+
+ PVR_ADDON_CAPABILITIES* m_capabilities;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_General_Inputstream_PVRStreamProperty class PVRStreamProperty
+/// @ingroup cpp_kodi_addon_pvr_Defs_General_Inputstream
+/// @brief **PVR stream property value handler**\n
+/// To set for Kodi wanted stream properties.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_General_Inputstream_PVRStreamProperty_Help
+///
+///---------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// ...
+///
+/// PVR_ERROR CMyPVRInstance::GetChannelStreamProperties(const kodi::addon::PVRChannel& channel,
+/// std::vector<kodi::addon::PVRStreamProperty>& properties)
+/// {
+/// ...
+/// properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "inputstream.adaptive");
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// ...
+/// ~~~~~~~~~~~~~
+///
+///
+/// **Example 2:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// ...
+///
+/// PVR_ERROR CMyPVRInstance::GetChannelStreamProperties(const kodi::addon::PVRChannel& channel,
+/// std::vector<kodi::addon::PVRStreamProperty>& properties)
+/// {
+/// ...
+/// kodi::addon::PVRStreamProperty property;
+/// property.SetName(PVR_STREAM_PROPERTY_INPUTSTREAM);
+/// property.SetValue("inputstream.adaptive");
+/// properties.emplace_back(property);
+/// return PVR_ERROR_NO_ERROR;
+/// }
+///
+/// ...
+/// ~~~~~~~~~~~~~
+///
+///@{
+class PVRStreamProperty : public CStructHdl<PVRStreamProperty, PVR_NAMED_VALUE>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRStreamProperty(const PVRStreamProperty& data) : CStructHdl(data) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_General_Inputstream_PVRStreamProperty_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_General_Inputstream_PVRStreamProperty
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_General_Inputstream_PVRStreamProperty :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Name** | `int` | @ref PVRStreamProperty::SetValue "SetName" | @ref PVRStreamProperty::GetName "GetName"
+ /// | **Value** | `std::string` | @ref PVRStreamProperty::SetValue "SetValue" | @ref PVRStreamProperty::GetValue "GetValue"
+ ///
+ /// @remark Further can there be used his class constructor to set values.
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_General_Inputstream_PVRStreamProperty
+ ///@{
+
+ /// @brief Default class constructor.
+ ///
+ /// @note Values must be set afterwards.
+ PVRStreamProperty() = default;
+
+ /// @brief Class constructor with integrated value set.
+ ///
+ /// @param[in] name Type identification
+ /// @param[in] value Type used property value
+ PVRStreamProperty(const std::string& name, const std::string& value)
+ {
+ SetName(name);
+ SetValue(value);
+ }
+
+ /// @brief To set with the identification name.
+ void SetName(const std::string& name)
+ {
+ strncpy(m_cStructure->strName, name.c_str(), sizeof(m_cStructure->strName) - 1);
+ }
+
+ /// @brief To get with the identification name.
+ std::string GetName() const { return m_cStructure->strName; }
+
+ /// @brief To set with the used property value.
+ void SetValue(const std::string& value)
+ {
+ strncpy(m_cStructure->strValue, value.c_str(), sizeof(m_cStructure->strValue) - 1);
+ }
+
+ /// @brief To get with the used property value.
+ std::string GetValue() const { return m_cStructure->strValue; }
+ ///@}
+
+private:
+ PVRStreamProperty(const PVR_NAMED_VALUE* data) : CStructHdl(data) {}
+ PVRStreamProperty(PVR_NAMED_VALUE* data) : CStructHdl(data) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/MenuHook.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/MenuHook.h
new file mode 100644
index 0000000..053a4d5
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/MenuHook.h
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr/pvr_menu_hook.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 7 - Menu hook
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook class PVRMenuhook
+/// @ingroup cpp_kodi_addon_pvr_Defs_Menuhook
+/// @brief **Context menu hook**\n
+/// Menu hooks that are available in the context menus while playing a stream via this add-on.
+/// And in the Live TV settings dialog.
+///
+/// Possible menu's given to Kodi.
+///
+/// This can be becomes used on this, if @ref kodi::addon::CInstancePVRClient::AddMenuHook()
+/// was set to related type:
+/// - @ref kodi::addon::CInstancePVRClient::CallSettingsMenuHook()
+/// - @ref kodi::addon::CInstancePVRClient::CallChannelMenuHook()
+/// - @ref kodi::addon::CInstancePVRClient::CallEPGMenuHook()
+/// - @ref kodi::addon::CInstancePVRClient::CallRecordingMenuHook()
+/// - @ref kodi::addon::CInstancePVRClient::CallTimerMenuHook()
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help
+///
+///@{
+class PVRMenuhook : public CStructHdl<PVRMenuhook, PVR_MENUHOOK>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook
+ /// @brief Optional class constructor with value set.
+ ///
+ /// @param[in] hookId This hook's identifier
+ /// @param[in] localizedStringId Localized string identifier
+ /// @param[in] category Category of menu hook, defined with @ref PVR_MENUHOOK_CAT
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// AddMenuHook(kodi::addon::PVRMenuhook(1, 30001, PVR_MENUHOOK_CHANNEL));
+ /// ~~~~~~~~~~~~~
+ ///
+ PVRMenuhook(unsigned int hookId, unsigned int localizedStringId, PVR_MENUHOOK_CAT category)
+ {
+ m_cStructure->iHookId = hookId;
+ m_cStructure->iLocalizedStringId = localizedStringId;
+ m_cStructure->category = category;
+ }
+
+ /*! \cond PRIVATE */
+ PVRMenuhook()
+ {
+ m_cStructure->iHookId = 0;
+ m_cStructure->iLocalizedStringId = 0;
+ m_cStructure->category = PVR_MENUHOOK_UNKNOWN;
+ }
+ PVRMenuhook(const PVRMenuhook& data) : CStructHdl(data) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **This hook's identifier** | `unsigned int` | @ref PVRMenuhook::SetHookId "SetHookId" | @ref PVRMenuhook::GetHookId "GetHookId" | *required to set*
+ /// | **Localized string Identifier** | `unsigned int` | @ref PVRMenuhook::SetLocalizedStringId "SetLocalizedStringId" | @ref PVRMenuhook::GetLocalizedStringId "GetLocalizedStringId" | *required to set*
+ /// | **Category of menu hook** | @ref PVR_MENUHOOK_CAT | @ref PVRMenuhook::SetCategory "SetCategory" | @ref PVRMenuhook::GetCategory "GetCategory" | *required to set*
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Menuhook_PVRMenuhook
+ ///@{
+
+ /// @brief **required**\n
+ /// This hook's identifier.
+ void SetHookId(unsigned int hookId) { m_cStructure->iHookId = hookId; }
+
+ /// @brief To get with @ref SetHookId() changed values.
+ unsigned int GetHookId() const { return m_cStructure->iHookId; }
+
+ /// @brief **required**\n
+ /// The id of the label for this hook in @ref kodi::GetLocalizedString().
+ void SetLocalizedStringId(unsigned int localizedStringId)
+ {
+ m_cStructure->iLocalizedStringId = localizedStringId;
+ }
+
+ /// @brief To get with @ref SetLocalizedStringId() changed values.
+ unsigned int GetLocalizedStringId() const { return m_cStructure->iLocalizedStringId; }
+
+ /// @brief **required**\n
+ /// Category of menu hook.
+ void SetCategory(PVR_MENUHOOK_CAT category) { m_cStructure->category = category; }
+
+ /// @brief To get with @ref SetCategory() changed values.
+ PVR_MENUHOOK_CAT GetCategory() const { return m_cStructure->category; }
+ ///@}
+
+private:
+ PVRMenuhook(const PVR_MENUHOOK* data) : CStructHdl(data) {}
+ PVRMenuhook(PVR_MENUHOOK* data) : CStructHdl(data) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Providers.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Providers.h
new file mode 100644
index 0000000..8ccd7a7
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Providers.h
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr.h"
+#include "../../tools/StringUtils.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 2 - PVR provider
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_PVRProvider class PVRProvider
+/// @ingroup cpp_kodi_addon_pvr_Defs_Provider
+/// @brief **Provider data structure**\n
+/// Representation of a provider.
+///
+/// This is used to store all the necessary provider data and can
+/// either provide the necessary data from / to Kodi for the associated
+/// functions or can also be used in the addon to store its data.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_PVRProvider_Help
+///
+///@{
+class PVRProvider : public CStructHdl<PVRProvider, PVR_PROVIDER>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRProvider() { memset(m_cStructure, 0, sizeof(PVR_PROVIDER)); }
+ PVRProvider(const PVRProvider& provider) : CStructHdl(provider) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_PVRProvider_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_PVRProvider
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_PVRProvider :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Unique id** | `unsigned int` | @ref PVRProvider::SetUniqueId "SetUniqueId" | @ref PVRProvider::GetUniqueId "GetUniqueId" | *required to set*
+ /// | **Provider name** | `std::string` | @ref PVRProvider::SetName "SetName" | @ref PVRProvider::GetName "GetName" | *required to set*
+ /// | **Provider type** | @ref PVR_PROVIDER_TYPE | @ref PVRProvider::SetType "SetType" | @ref PVRProvider::GetType "GetType" | *optional*
+ /// | **Icon path** | `std::string` | @ref PVRProvider::SetIconPath "SetIconPath" | @ref PVRProvider::GetIconPath "GetIconPath" | *optional*
+ /// | **Countries** | `std::vector<std::string>` | @ref PVRProvider::SetCountries "SetCountries" | @ref PVRProvider::GetCountries "GetCountries" | *optional*
+ /// | **Languages** | `std::vector<std::string>` | @ref PVRProvider::SetLanguages "SetLanguages" | @ref PVRProvider::GetLanguages "GetLanguages" | *optional*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_PVRProvider
+ ///@{
+
+ /// @brief **required**\n
+ /// Unique identifier for this provider.
+ void SetUniqueId(unsigned int uniqueId) { m_cStructure->iUniqueId = uniqueId; }
+
+ /// @brief To get with @ref SetUniqueId changed values.
+ unsigned int GetUniqueId() const { return m_cStructure->iUniqueId; }
+
+ /// @brief **required**\n
+ /// Name given to this provider.
+ void SetName(const std::string& name)
+ {
+ strncpy(m_cStructure->strName, name.c_str(), sizeof(m_cStructure->strName) - 1);
+ }
+
+ /// @brief To get with @ref SetName changed values.
+ std::string GetName() const { return m_cStructure->strName; }
+
+ /// @brief **optional**\n
+ /// Provider type.
+ ///
+ /// Set to @ref PVR_PROVIDER_TYPE_UNKNOWN if the type cannot be
+ /// determined.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRProvider tag;
+ /// tag.SetType(PVR_PROVIDER_TYPE_SATELLITE);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetType(PVR_PROVIDER_TYPE type) { m_cStructure->type = type; }
+
+ /// @brief To get with @ref SetType changed values
+ PVR_PROVIDER_TYPE GetType() const { return m_cStructure->type; }
+
+ /// @brief **optional**\n
+ /// Path to the provider icon (if present).
+ void SetIconPath(const std::string& iconPath)
+ {
+ strncpy(m_cStructure->strIconPath, iconPath.c_str(), sizeof(m_cStructure->strIconPath) - 1);
+ }
+
+ /// @brief To get with @ref SetIconPath changed values.
+ std::string GetIconPath() const { return m_cStructure->strIconPath; }
+ ///@}
+
+ /// @brief **optional**\n
+ /// The country codes for the provider.
+ ///
+ /// @note ISO 3166 country codes required (e.g 'GB,IE,CA').
+ void SetCountries(const std::vector<std::string>& countries)
+ {
+ const std::string str = tools::StringUtils::Join(countries, PROVIDER_STRING_TOKEN_SEPARATOR);
+ strncpy(m_cStructure->strCountries, str.c_str(), sizeof(m_cStructure->strCountries) - 1);
+ }
+
+ /// @brief To get with @ref SetCountries changed values.
+ std::vector<std::string> GetCountries() const
+ {
+ return tools::StringUtils::Split(m_cStructure->strCountries, PROVIDER_STRING_TOKEN_SEPARATOR);
+ }
+ ///@}
+
+ /// @brief **optional**\n
+ /// The language codes for the provider.
+ ///
+ /// @note RFC 5646 standard codes required (e.g.: 'en_GB,fr_CA').
+ void SetLanguages(const std::vector<std::string>& languages)
+ {
+ const std::string str = tools::StringUtils::Join(languages, PROVIDER_STRING_TOKEN_SEPARATOR);
+ strncpy(m_cStructure->strLanguages, str.c_str(), sizeof(m_cStructure->strLanguages) - 1);
+ }
+
+ /// @brief To get with @ref SetLanguages changed values.
+ std::vector<std::string> GetLanguages() const
+ {
+ return tools::StringUtils::Split(m_cStructure->strLanguages, PROVIDER_STRING_TOKEN_SEPARATOR);
+ }
+ ///@}
+
+private:
+ PVRProvider(const PVR_PROVIDER* provider) : CStructHdl(provider) {}
+ PVRProvider(PVR_PROVIDER* provider) : CStructHdl(provider) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_PVRProvidersResultSet class PVRProvidersResultSet
+/// @ingroup cpp_kodi_addon_pvr_Defs_PVRProvider
+/// @brief **PVR add-on provider transfer class**\n
+/// To transfer the content of @ref kodi::addon::CInstancePVRClient::GetProviders().
+///
+///@{
+class PVRProvidersResultSet
+{
+public:
+ /*! \cond PRIVATE */
+ PVRProvidersResultSet() = delete;
+ PVRProvidersResultSet(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ : m_instance(instance), m_handle(handle)
+ {
+ }
+ /*! \endcond */
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_PVRProvidersResultSet
+ ///@{
+
+ /// @brief To add and give content from addon to Kodi on related call.
+ ///
+ /// @param[in] provider The to transferred data.
+ void Add(const kodi::addon::PVRProvider& provider)
+ {
+ m_instance->toKodi->TransferProviderEntry(m_instance->toKodi->kodiInstance, m_handle, provider);
+ }
+
+ ///@}
+
+private:
+ const AddonInstance_PVR* m_instance = nullptr;
+ const PVR_HANDLE m_handle;
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Recordings.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Recordings.h
new file mode 100644
index 0000000..b7f498a
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Recordings.h
@@ -0,0 +1,545 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 5 - PVR recordings
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecording class PVRRecording
+/// @ingroup cpp_kodi_addon_pvr_Defs_Recording
+/// @brief **Data structure with available recordings data**\n
+/// With this, recordings related data are transferred between addon and Kodi
+/// and can also be used by the addon itself.
+///
+/// The related values here are automatically initiated to defaults and need
+/// only be set if supported and used.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Recording_PVRRecording_Help
+///
+///@{
+class PVRRecording : public CStructHdl<PVRRecording, PVR_RECORDING>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRRecording()
+ {
+ m_cStructure->iSeriesNumber = PVR_RECORDING_INVALID_SERIES_EPISODE;
+ m_cStructure->iEpisodeNumber = PVR_RECORDING_INVALID_SERIES_EPISODE;
+ m_cStructure->recordingTime = 0;
+ m_cStructure->iDuration = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->iPriority = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->iLifetime = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->iGenreType = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->iGenreSubType = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->iPlayCount = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->iLastPlayedPosition = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->bIsDeleted = false;
+ m_cStructure->iEpgEventId = 0;
+ m_cStructure->iChannelUid = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ m_cStructure->channelType = PVR_RECORDING_CHANNEL_TYPE_UNKNOWN;
+ m_cStructure->iFlags = 0;
+ m_cStructure->sizeInBytes = PVR_RECORDING_VALUE_NOT_AVAILABLE;
+ }
+ PVRRecording(const PVRRecording& recording) : CStructHdl(recording) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecording_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Recording_PVRRecording :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Recording id** | `std::string` | @ref PVRRecording::SetRecordingId "SetRecordingId" | @ref PVRRecording::GetRecordingId "GetRecordingId" | *required to set*
+ /// | **Title** | `std::string` | @ref PVRRecording::SetTitle "SetTitle" | @ref PVRRecording::GetTitle "GetTitle" | *required to set*
+ /// | **Episode name** | `std::string` | @ref PVRRecording::SetEpisodeName "SetEpisodeName" | @ref PVRRecording::GetEpisodeName "GetEpisodeName" | *optional*
+ /// | **Series number** | `int` | @ref PVRRecording::SetSeriesNumber "SetSeriesNumber" | @ref PVRRecording::GetSeriesNumber "GetSeriesNumber" | *optional*
+ /// | **Episode number** | `int` | @ref PVRRecording::SetEpisodeNumber "SetEpisodeNumber" | @ref PVRRecording::GetEpisodeNumber "GetEpisodeNumber" | *optional*
+ /// | **Year** | `int` | @ref PVRRecording::SetYear "SetYear" | @ref PVRRecording::GetYear "GetYear" | *optional*
+ /// | **Directory** | `std::string` | @ref PVRRecording::SetDirectory "SetDirectory" | @ref PVRRecording::GetDirectory "GetDirectory" | *optional*
+ /// | **Plot outline** | `std::string` | @ref PVRRecording::SetPlotOutline "SetPlotOutline" | @ref PVRRecording::GetPlotOutline "GetPlotOutline" | *optional*
+ /// | **Plot** | `std::string` | @ref PVRRecording::SetPlot "SetPlot" | @ref PVRRecording::GetPlot "GetPlot" | *optional*
+ /// | **Genre description** | `std::string` | @ref PVRRecording::SetGenreDescription "SetGenreDescription" | @ref PVRRecording::GetGenreDescription "GetGenreDescription" | *optional*
+ /// | **Channel name** | `std::string` | @ref PVRRecording::SetChannelName "SetChannelName" | @ref PVRRecording::GetChannelName "GetChannelName" | *optional*
+ /// | **Icon path** | `std::string` | @ref PVRRecording::SetIconPath "SetIconPath" | @ref PVRRecording::GetIconPath "GetIconPath" | *optional*
+ /// | **Thumbnail path** | `std::string` | @ref PVRRecording::SetThumbnailPath "SetThumbnailPath" | @ref PVRRecording::GetThumbnailPath "GetThumbnailPath" | *optional*
+ /// | **Fanart path** | `std::string` | @ref PVRRecording::SetFanartPath "SetFanartPath" | @ref PVRRecording::GetFanartPath "GetFanartPath" | *optional*
+ /// | **Recording time** | `time_t` | @ref PVRRecording::SetRecordingTime "SetRecordingTime" | @ref PVRRecording::GetRecordingTime "GetRecordingTime" | *optional*
+ /// | **Duration** | `int` | @ref PVRRecording::SetDuration "SetDuration" | @ref PVRRecording::GetDuration "GetDuration" | *optional*
+ /// | **Priority** | `int` | @ref PVRRecording::SetPriority "SetPriority" | @ref PVRRecording::GetPriority "GetPriority" | *optional*
+ /// | **Lifetime** | `int` | @ref PVRRecording::SetLifetime "SetLifetime" | @ref PVRRecording::GetLifetime "GetLifetime" | *optional*
+ /// | **Genre type** | `int` | @ref PVRRecording::SetGenreType "SetGenreType" | @ref PVRRecording::GetGenreType "GetGenreType" | *optional*
+ /// | **Genre sub type** | `int` | @ref PVRRecording::SetGenreSubType "SetGenreSubType" | @ref PVRRecording::GetGenreSubType "GetGenreSubType" | *optional*
+ /// | **Play count** | `int` | @ref PVRRecording::SetPlayCount "SetPlayCount" | @ref PVRRecording::GetPlayCount "GetPlayCount" | *optional*
+ /// | **Last played position** | `int` | @ref PVRRecording::SetLastPlayedPosition "SetLastPlayedPosition" | @ref PVRRecording::GetLastPlayedPosition "GetLastPlayedPosition" | *optional*
+ /// | **Is deleted** | `bool` | @ref PVRRecording::SetIsDeleted "SetIsDeleted" | @ref PVRRecording::GetIsDeleted "GetIsDeleted" | *optional*
+ /// | **EPG event id** | `unsigned int` | @ref PVRRecording::SetEPGEventId "SetEPGEventId" | @ref PVRRecording::GetEPGEventId "GetEPGEventId" | *optional*
+ /// | **Channel unique id** | `int` | @ref PVRRecording::SetChannelUid "SetChannelUid" | @ref PVRRecording::GetChannelUid "GetChannelUid" | *optional*
+ /// | **Channel type** | @ref PVR_RECORDING_CHANNEL_TYPE | @ref PVRRecording::SetChannelType "SetChannelType" | @ref PVRRecording::GetChannelType "GetChannelType" | *optional*
+ /// | **First aired** | `std::string` | @ref PVRRecording::SetFirstAired "SetFirstAired" | @ref PVRRecording::GetFirstAired "GetFirstAired" | *optional*
+ /// | **Flags** | `std::string` | @ref PVRRecording::SetFlags "SetFlags" | @ref PVRRecording::GetFlags "GetFlags" | *optional*
+ /// | **Size in bytes** | `std::string` | @ref PVRRecording::SetSizeInBytes "SetSizeInBytes" | @ref PVRRecording::GetSizeInBytes "GetSizeInBytes" | *optional*
+ /// | **Client provider unique identifier** | `int` | @ref PVRChannel::SetClientProviderUid "SetClientProviderUid" | @ref PVRTimer::GetClientProviderUid "GetClientProviderUid" | *optional*
+ /// | **Provider name** | `std::string` | @ref PVRChannel::SetProviderName "SetProviderlName" | @ref PVRChannel::GetProviderName "GetProviderName" | *optional*
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ ///@{
+
+ /// @brief **required**\n
+ /// Unique identifier of the recording on the client.
+ void SetRecordingId(const std::string& recordingId)
+ {
+ strncpy(m_cStructure->strRecordingId, recordingId.c_str(),
+ sizeof(m_cStructure->strRecordingId) - 1);
+ }
+
+ /// @brief To get with @ref SetRecordingId changed values.
+ std::string GetRecordingId() const { return m_cStructure->strRecordingId; }
+
+ /// @brief **required**\n
+ /// The title of this recording.
+ void SetTitle(const std::string& title)
+ {
+ strncpy(m_cStructure->strTitle, title.c_str(), sizeof(m_cStructure->strTitle) - 1);
+ }
+
+ /// @brief To get with @ref SetTitle changed values.
+ std::string GetTitle() const { return m_cStructure->strTitle; }
+
+ /// @brief **optional**\n
+ /// Episode name (also known as subtitle).
+ void SetEpisodeName(const std::string& episodeName)
+ {
+ strncpy(m_cStructure->strEpisodeName, episodeName.c_str(),
+ sizeof(m_cStructure->strEpisodeName) - 1);
+ }
+
+ /// @brief To get with @ref SetEpisodeName changed values.
+ std::string GetEpisodeName() const { return m_cStructure->strEpisodeName; }
+
+ /// @brief **optional**\n
+ /// Series number (usually called season).
+ ///
+ /// Set to "0" for specials/pilot. For 'invalid' see @ref SetEpisodeNumber or set to -1.
+ void SetSeriesNumber(int seriesNumber) { m_cStructure->iSeriesNumber = seriesNumber; }
+
+ /// @brief To get with @ref SetSeriesNumber changed values.
+ int GetSeriesNumber() const { return m_cStructure->iSeriesNumber; }
+
+ /// @brief **optional**\n
+ /// Eepisode number within the "iSeriesNumber" season.
+ ///
+ /// For 'invalid' set to -1 or seriesNumber=episodeNumber=0 to show both are invalid.
+ void SetEpisodeNumber(int episodeNumber) { m_cStructure->iEpisodeNumber = episodeNumber; }
+
+ /// @brief To get with @ref SetEpisodeNumber changed values.
+ int GetEpisodeNumber() const { return m_cStructure->iEpisodeNumber; }
+
+ /// @brief **optional**\n
+ /// Year of first release (use to identify a specific movie re-make) / first
+ /// airing for TV shows.
+ ///
+ /// Set to '0' for invalid.
+ void SetYear(int year) { m_cStructure->iYear = year; }
+
+ /// @brief To get with @ref SetYear changed values.
+ int GetYear() const { return m_cStructure->iYear; }
+
+ /// @brief **optional**\n
+ ///
+ /// Directory of this recording on the client.
+ void SetDirectory(const std::string& directory)
+ {
+ strncpy(m_cStructure->strDirectory, directory.c_str(), sizeof(m_cStructure->strDirectory) - 1);
+ }
+
+ /// @brief To get with @ref SetDirectory changed values.
+ std::string GetDirectory() const { return m_cStructure->strDirectory; }
+
+ /// @brief **optional**\n
+ /// Plot outline name.
+ void SetPlotOutline(const std::string& plotOutline)
+ {
+ strncpy(m_cStructure->strPlotOutline, plotOutline.c_str(),
+ sizeof(m_cStructure->strPlotOutline) - 1);
+ }
+
+ /// @brief To get with @ref SetPlotOutline changed values.
+ std::string GetPlotOutline() const { return m_cStructure->strPlotOutline; }
+
+ /// @brief **optional**\n
+ /// Plot name.
+ void SetPlot(const std::string& plot)
+ {
+ strncpy(m_cStructure->strPlot, plot.c_str(), sizeof(m_cStructure->strPlot) - 1);
+ }
+
+ /// @brief To get with @ref SetPlot changed values.
+ std::string GetPlot() const { return m_cStructure->strPlot; }
+
+ /// @brief **optional**\n
+ /// Channel name.
+ void SetChannelName(const std::string& channelName)
+ {
+ strncpy(m_cStructure->strChannelName, channelName.c_str(),
+ sizeof(m_cStructure->strChannelName) - 1);
+ }
+
+ /// @brief To get with @ref SetChannelName changed values.
+ std::string GetChannelName() const { return m_cStructure->strChannelName; }
+
+ /// @brief **optional**\n
+ /// Channel logo (icon) path.
+ void SetIconPath(const std::string& iconPath)
+ {
+ strncpy(m_cStructure->strIconPath, iconPath.c_str(), sizeof(m_cStructure->strIconPath) - 1);
+ }
+
+ /// @brief To get with @ref SetIconPath changed values.
+ std::string GetIconPath() const { return m_cStructure->strIconPath; }
+
+ /// @brief **optional**\n
+ /// Thumbnail path.
+ void SetThumbnailPath(const std::string& thumbnailPath)
+ {
+ strncpy(m_cStructure->strThumbnailPath, thumbnailPath.c_str(),
+ sizeof(m_cStructure->strThumbnailPath) - 1);
+ }
+
+ /// @brief To get with @ref SetThumbnailPath changed values.
+ std::string GetThumbnailPath() const { return m_cStructure->strThumbnailPath; }
+
+ /// @brief **optional**\n
+ /// Fanart path.
+ void SetFanartPath(const std::string& fanartPath)
+ {
+ strncpy(m_cStructure->strFanartPath, fanartPath.c_str(),
+ sizeof(m_cStructure->strFanartPath) - 1);
+ }
+
+ /// @brief To get with @ref SetFanartPath changed values.
+ std::string GetFanartPath() const { return m_cStructure->strFanartPath; }
+
+ /// @brief **optional**\n
+ /// Start time of the recording.
+ void SetRecordingTime(time_t recordingTime) { m_cStructure->recordingTime = recordingTime; }
+
+ /// @brief To get with @ref SetRecordingTime changed values.
+ time_t GetRecordingTime() const { return m_cStructure->recordingTime; }
+
+ /// @brief **optional**\n
+ /// Duration of the recording in seconds.
+ void SetDuration(int duration) { m_cStructure->iDuration = duration; }
+
+ /// @brief To get with @ref SetDuration changed values.
+ int GetDuration() const { return m_cStructure->iDuration; }
+
+ /// @brief **optional**\n
+ /// Priority of this recording (from 0 - 100).
+ void SetPriority(int priority) { m_cStructure->iPriority = priority; }
+
+ /// @brief To get with @ref SetPriority changed values.
+ int GetPriority() const { return m_cStructure->iPriority; }
+
+ /// @brief **optional**\n
+ /// Life time in days of this recording.
+ void SetLifetime(int lifetime) { m_cStructure->iLifetime = lifetime; }
+
+ /// @brief To get with @ref SetLifetime changed values.
+ int GetLifetime() const { return m_cStructure->iLifetime; }
+
+ /// @brief **optional**\n
+ /// Genre type.
+ ///
+ /// Use @ref EPG_GENRE_USE_STRING if type becomes given by @ref SetGenreDescription.
+ ///
+ /// @note If confirmed that backend brings the types in [ETSI EN 300 468](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf)
+ /// conform values, can be @ref EPG_EVENT_CONTENTMASK ignored and to set here
+ /// with backend value.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example 1:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRRecording tag;
+ /// tag.SetGenreType(EPG_EVENT_CONTENTMASK_MOVIEDRAMA);
+ /// ~~~~~~~~~~~~~
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example 2** (in case of other, not ETSI EN 300 468 conform genre types):
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRRecording tag;
+ /// tag.SetGenreType(EPG_GENRE_USE_STRING);
+ /// tag.SetGenreDescription("My special genre name"); // Should use (if possible) kodi::GetLocalizedString(...) to have match user language.
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetGenreType(int genreType) { m_cStructure->iGenreType = genreType; }
+
+ /// @brief To get with @ref SetGenreType changed values.
+ int GetGenreType() const { return m_cStructure->iGenreType; }
+
+ /// @brief **optional**\n
+ /// Genre sub type.
+ ///
+ /// Subtypes groups related to set by @ref SetGenreType:
+ /// | Main genre type | List with available sub genre types
+ /// |-----------------|-----------------------------------------
+ /// | @ref EPG_EVENT_CONTENTMASK_UNDEFINED | Nothing, should be 0
+ /// | @ref EPG_EVENT_CONTENTMASK_MOVIEDRAMA | @ref EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA
+ /// | @ref EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS | @ref EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS
+ /// | @ref EPG_EVENT_CONTENTMASK_SHOW | @ref EPG_EVENT_CONTENTSUBMASK_SHOW
+ /// | @ref EPG_EVENT_CONTENTMASK_SPORTS | @ref EPG_EVENT_CONTENTSUBMASK_SPORTS
+ /// | @ref EPG_EVENT_CONTENTMASK_CHILDRENYOUTH | @ref EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH
+ /// | @ref EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE | @ref EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE
+ /// | @ref EPG_EVENT_CONTENTMASK_ARTSCULTURE | @ref EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE
+ /// | @ref EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS | @ref EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS
+ /// | @ref EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE | @ref EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE
+ /// | @ref EPG_EVENT_CONTENTMASK_LEISUREHOBBIES | @ref EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES
+ /// | @ref EPG_EVENT_CONTENTMASK_SPECIAL | @ref EPG_EVENT_CONTENTSUBMASK_SPECIAL
+ /// | @ref EPG_EVENT_CONTENTMASK_USERDEFINED | Can be defined by you
+ /// | @ref EPG_GENRE_USE_STRING | **Kodi's own value**, which declares that the type with @ref SetGenreDescription is given.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRRecording tag;
+ /// tag.SetGenreType(EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE);
+ /// tag.SetGenreSubType(EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_JAZZ);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetGenreSubType(int genreSubType) { m_cStructure->iGenreSubType = genreSubType; }
+
+ /// @brief To get with @ref SetGenreSubType changed values.
+ int GetGenreSubType() const { return m_cStructure->iGenreSubType; }
+
+ /// @brief **optional**\n
+ /// To set own genre description name.
+ ///
+ /// Will be used only when genreType == @ref EPG_GENRE_USE_STRING or
+ /// genreSubType == @ref EPG_GENRE_USE_STRING.
+ ///
+ /// Use @ref EPG_STRING_TOKEN_SEPARATOR to separate different genres.
+ ///
+ /// In case of other, not [ETSI EN 300 468](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf)
+ /// conform genre types or something special.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRRecording tag;
+ /// tag.SetGenreType(EPG_GENRE_USE_STRING);
+ /// tag.SetGenreDescription("Action" + EPG_STRING_TOKEN_SEPARATOR + "Thriller");
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetGenreDescription(const std::string& genreDescription)
+ {
+ strncpy(m_cStructure->strGenreDescription, genreDescription.c_str(),
+ sizeof(m_cStructure->strGenreDescription) - 1);
+ }
+
+ /// @brief To get with @ref SetGenreDescription changed values.
+ std::string GetGenreDescription() const { return m_cStructure->strGenreDescription; }
+
+ /// @brief **optional**\n
+ /// Play count of this recording on the client.
+ void SetPlayCount(int playCount) { m_cStructure->iPlayCount = playCount; }
+
+ /// @brief To get with @ref SetPlayCount changed values.
+ int GetPlayCount() const { return m_cStructure->iPlayCount; }
+
+ /// @brief **optional**\n
+ /// Last played position of this recording on the client.
+ void SetLastPlayedPosition(int lastPlayedPosition)
+ {
+ m_cStructure->iLastPlayedPosition = lastPlayedPosition;
+ }
+
+ /// @brief To get with @ref SetLastPlayedPosition changed values.
+ int GetLastPlayedPosition() const { return m_cStructure->iLastPlayedPosition; }
+
+ /// @brief **optional**\n
+ /// Shows this recording is deleted and can be undelete.
+ void SetIsDeleted(int isDeleted) { m_cStructure->bIsDeleted = isDeleted; }
+
+ /// @brief To get with @ref SetIsDeleted changed values.
+ int GetIsDeleted() const { return m_cStructure->bIsDeleted; }
+
+ /// @brief **optional**\n
+ /// EPG event id associated with this recording. Valid ids must be greater than @ref EPG_TAG_INVALID_UID.
+ void SetEPGEventId(unsigned int epgEventId) { m_cStructure->iEpgEventId = epgEventId; }
+
+ /// @brief To get with @ref SetEPGEventId changed values.
+ unsigned int GetEPGEventId() const { return m_cStructure->iEpgEventId; }
+
+ /// @brief **optional**\n
+ /// Unique identifier of the channel for this recording. @ref PVR_CHANNEL_INVALID_UID
+ /// denotes that channel uid is not available.
+ void SetChannelUid(int channelUid) { m_cStructure->iChannelUid = channelUid; }
+
+ /// @brief To get with @ref SetChannelUid changed values
+ int GetChannelUid() const { return m_cStructure->iChannelUid; }
+
+ /// @brief **optional**\n
+ /// Channel type.
+ ///
+ /// Set to @ref PVR_RECORDING_CHANNEL_TYPE_UNKNOWN if the type cannot be
+ /// determined.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRRecording tag;
+ /// tag.SetChannelType(PVR_RECORDING_CHANNEL_TYPE_TV);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetChannelType(PVR_RECORDING_CHANNEL_TYPE channelType)
+ {
+ m_cStructure->channelType = channelType;
+ }
+
+ /// @brief To get with @ref SetChannelType changed values
+ PVR_RECORDING_CHANNEL_TYPE GetChannelType() const { return m_cStructure->channelType; }
+
+ /// @brief **optional**\n
+ /// First aired date of this recording.
+ ///
+ /// Used only for display purposes. Specify in W3C date format "YYYY-MM-DD".
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRRecording tag;
+ /// tag.SetFirstAired(1982-10-22);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetFirstAired(const std::string& firstAired)
+ {
+ strncpy(m_cStructure->strFirstAired, firstAired.c_str(),
+ sizeof(m_cStructure->strFirstAired) - 1);
+ }
+
+ /// @brief To get with @ref SetFirstAired changed values
+ std::string GetFirstAired() const { return m_cStructure->strFirstAired; }
+
+ /// @brief **optional**\n
+ /// Bit field of independent flags associated with the recording.
+ ///
+ /// See @ref cpp_kodi_addon_pvr_Defs_Recording_PVR_RECORDING_FLAG for
+ /// available bit flags.
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_Recording_PVR_RECORDING_FLAG
+ ///
+ void SetFlags(unsigned int flags) { m_cStructure->iFlags = flags; }
+
+ /// @brief To get with @ref SetFlags changed values.
+ unsigned int GetFlags() const { return m_cStructure->iFlags; }
+
+ /// @brief **optional**\n
+ /// Size of the recording in bytes.
+ void SetSizeInBytes(int64_t sizeInBytes) { m_cStructure->sizeInBytes = sizeInBytes; }
+
+ /// @brief To get with @ref SetSizeInBytes changed values.
+ int64_t GetSizeInBytes() const { return m_cStructure->sizeInBytes; }
+ ///@}
+
+ /// @brief **optional**\n
+ /// Unique identifier of the provider this channel belongs to.
+ ///
+ /// @ref PVR_PROVIDER_INVALID_UID denotes that provider uid is not available.
+ void SetClientProviderUid(int iClientProviderUid)
+ {
+ m_cStructure->iClientProviderUid = iClientProviderUid;
+ }
+
+ /// @brief To get with @ref SetClientProviderUid changed values
+ int GetClientProviderUid() const { return m_cStructure->iClientProviderUid; }
+
+ /// @brief **optional**\n
+ /// Name for the provider of this channel.
+ void SetProviderName(const std::string& providerName)
+ {
+ strncpy(m_cStructure->strProviderName, providerName.c_str(),
+ sizeof(m_cStructure->strProviderName) - 1);
+ }
+
+ /// @brief To get with @ref SetProviderName changed values.
+ std::string GetProviderName() const { return m_cStructure->strProviderName; }
+
+private:
+ PVRRecording(const PVR_RECORDING* recording) : CStructHdl(recording) {}
+ PVRRecording(PVR_RECORDING* recording) : CStructHdl(recording) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecordingsResultSet class PVRRecordingsResultSet
+/// @ingroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+/// @brief **PVR add-on recording transfer class**\n
+/// To transfer the content of @ref kodi::addon::CInstancePVRClient::GetRecordings().
+///
+/// @note This becomes only be used on addon call above, not usable outside on
+/// addon itself.
+///@{
+class PVRRecordingsResultSet
+{
+public:
+ /*! \cond PRIVATE */
+ PVRRecordingsResultSet() = delete;
+ PVRRecordingsResultSet(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ : m_instance(instance), m_handle(handle)
+ {
+ }
+ /*! \endcond */
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecordingsResultSet
+ ///@{
+
+ /// @brief To add and give content from addon to Kodi on related call.
+ ///
+ /// @param[in] tag The to transferred data.
+ void Add(const kodi::addon::PVRRecording& tag)
+ {
+ m_instance->toKodi->TransferRecordingEntry(m_instance->toKodi->kodiInstance, m_handle, tag);
+ }
+
+ ///@}
+
+private:
+ const AddonInstance_PVR* m_instance = nullptr;
+ const PVR_HANDLE m_handle;
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Stream.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Stream.h
new file mode 100644
index 0000000..4241c23
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Stream.h
@@ -0,0 +1,330 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr/pvr_stream.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 9 - PVR stream definitions (NOTE: Becomes replaced
+// in future by inputstream addon instance way)
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVRCodec class PVRCodec
+/// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+/// @brief **PVR codec identifier**\n
+/// Used to exchange the desired codec type between Kodi and addon.
+///
+/// @ref kodi::addon::CInstancePVRClient::GetCodecByName is used to get this data.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Stream_PVRCodec_Help
+///
+///@{
+class PVRCodec : public CStructHdl<PVRCodec, PVR_CODEC>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRCodec()
+ {
+ m_cStructure->codec_type = PVR_CODEC_TYPE_UNKNOWN;
+ m_cStructure->codec_id = PVR_INVALID_CODEC_ID;
+ }
+ PVRCodec(const PVRCodec& type) : CStructHdl(type) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVRCodec_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream_PVRCodec
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Stream_PVRCodec :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Codec type** | @ref PVR_CODEC_TYPE | @ref PVRCodec::SetCodecType "SetCodecType" | @ref PVRCodec::GetCodecType "GetCodecType"
+ /// | **Codec identifier** | `unsigned int` | @ref PVRCodec::SetCodecId "SetCodecId" | @ref PVRCodec::GetCodecId "GetCodecId"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Stream_PVRCodec
+ ///@{
+
+ /// @brief Codec type.
+ void SetCodecType(PVR_CODEC_TYPE codecType) { m_cStructure->codec_type = codecType; }
+
+ /// @brief To get with @ref SetCodecType() changed values.
+ PVR_CODEC_TYPE GetCodecType() const { return m_cStructure->codec_type; }
+
+ /// @brief Codec id.
+ ///
+ /// Related codec identifier, normally match the ffmpeg id's.
+ void SetCodecId(unsigned int codecId) { m_cStructure->codec_id = codecId; }
+
+ /// @brief To get with @ref SetCodecId() changed values.
+ unsigned int GetCodecId() const { return m_cStructure->codec_id; }
+ ///@}
+
+private:
+ PVRCodec(const PVR_CODEC& type) : CStructHdl(&type) {}
+ PVRCodec(const PVR_CODEC* type) : CStructHdl(type) {}
+ PVRCodec(PVR_CODEC* type) : CStructHdl(type) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties class PVRStreamProperties
+/// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+/// @brief **PVR stream properties**\n
+/// All information about a respective stream is stored in this, so that Kodi
+/// can process the data given by the addon after demux.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties_Help
+///
+///@{
+class PVRStreamProperties
+ : public CStructHdl<PVRStreamProperties, PVR_STREAM_PROPERTIES::PVR_STREAM>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRStreamProperties() { memset(m_cStructure, 0, sizeof(PVR_STREAM_PROPERTIES::PVR_STREAM)); }
+ PVRStreamProperties(const PVRStreamProperties& type) : CStructHdl(type) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **PID** | `unsigned int` | @ref PVRStreamProperties::SetPID "SetPID" | @ref PVRStreamProperties::GetPID "GetPID"
+ /// | **Codec type** | @ref PVR_CODEC_TYPE | @ref PVRStreamProperties::SetCodecType "SetCodecType" | @ref PVRStreamProperties::GetCodecType "GetCodecType"
+ /// | **Codec identifier** | `unsigned int` | @ref PVRStreamProperties::SetCodecId "SetCodecId" | @ref PVRStreamProperties::GetCodecId "GetCodecId"
+ /// | **Language** | `std::string` | @ref PVRStreamProperties::SetLanguage "SetLanguage" | @ref PVRStreamProperties::GetLanguage "GetLanguage"
+ /// | **Subtitle info** | `int` | @ref PVRStreamProperties::SetSubtitleInfo "SetSubtitleInfo" | @ref PVRStreamProperties::GetSubtitleInfo "GetSubtitleInfo"
+ /// | **FPS scale** | `int` | @ref PVRStreamProperties::SetFPSScale "SetFPSScale" | @ref PVRStreamProperties::GetFPSScale "GetFPSScale"
+ /// | **FPS rate** | `int` | @ref PVRStreamProperties::SetFPSRate "SetFPSRate" | @ref PVRStreamProperties::GetFPSRate "GetFPSRate"
+ /// | **Height** | `int` | @ref PVRStreamProperties::SetHeight "SetHeight" | @ref PVRStreamProperties::GetHeight "GetHeight"
+ /// | **Width** | `int` | @ref PVRStreamProperties::SetWidth "SetWidth" | @ref PVRStreamProperties::GetWidth "GetWidth"
+ /// | **Aspect ratio** | `float` | @ref PVRStreamProperties::SetAspect "SetAspect" | @ref PVRStreamProperties::GetAspect "GetAspect"
+ /// | **Channels** | `int` | @ref PVRStreamProperties::SetChannels "SetChannels" | @ref PVRStreamProperties::GetChannels "GetChannels"
+ /// | **Samplerate** | `int` | @ref PVRStreamProperties::SetSampleRate "SetSampleRate" | @ref PVRStreamProperties::GetSampleRate "GetSampleRate"
+ /// | **Block align** | `int` | @ref PVRStreamProperties::SetBlockAlign "SetBlockAlign" | @ref PVRStreamProperties::GetBlockAlign "GetBlockAlign"
+ /// | **Bit rate** | `int` | @ref PVRStreamProperties::SetBitRate "SetBitRate" | @ref PVRStreamProperties::GetBitRate "GetBitRate"
+ /// | **Bits per sample** | `int` | @ref PVRStreamProperties::SetBitsPerSample "SetBitsPerSample" | @ref PVRStreamProperties::GetBitsPerSample "GetBitsPerSample"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties
+ ///@{
+
+ /// @brief PID.
+ void SetPID(unsigned int pid) { m_cStructure->iPID = pid; }
+
+ /// @brief To get with @ref SetPID() changed values.
+ unsigned int GetPID() const { return m_cStructure->iPID; }
+
+ /// @brief Codec type this stream.
+ void SetCodecType(PVR_CODEC_TYPE codecType) { m_cStructure->iCodecType = codecType; }
+
+ /// @brief To get with @ref SetCodecType() changed values.
+ PVR_CODEC_TYPE GetCodecType() const { return m_cStructure->iCodecType; }
+
+ /// @brief Codec id of this stream.
+ void SetCodecId(unsigned int codecId) { m_cStructure->iCodecId = codecId; }
+
+ /// @brief To get with @ref SetCodecId() changed values.
+ unsigned int GetCodecId() const { return m_cStructure->iCodecId; }
+
+ /// @brief 3 letter language id.
+ void SetLanguage(const std::string& language)
+ {
+ if (language.size() > 3)
+ {
+ kodi::Log(ADDON_LOG_ERROR,
+ "PVRStreamProperties::%s: Language string size '%li' higher as needed 3", __func__,
+ language.size());
+ return;
+ }
+ m_cStructure->strLanguage[0] = language[0];
+ m_cStructure->strLanguage[1] = language[1];
+ m_cStructure->strLanguage[2] = language[2];
+ m_cStructure->strLanguage[3] = 0;
+ }
+
+ /// @brief To get with @ref SetLanguage() changed values.
+ std::string GetLanguage() const { return m_cStructure->strLanguage; }
+
+ /// @brief Subtitle Info
+ void SetSubtitleInfo(int subtitleInfo) { m_cStructure->iSubtitleInfo = subtitleInfo; }
+
+ /// @brief To get with @ref SetSubtitleInfo() changed values.
+ int GetSubtitleInfo() const { return m_cStructure->iSubtitleInfo; }
+
+ /// @brief To set scale of 1000 and a rate of 29970 will result in 29.97 fps.
+ void SetFPSScale(int fpsScale) { m_cStructure->iFPSScale = fpsScale; }
+
+ /// @brief To get with @ref SetFPSScale() changed values.
+ int GetFPSScale() const { return m_cStructure->iFPSScale; }
+
+ /// @brief FPS rate
+ void SetFPSRate(int fpsRate) { m_cStructure->iFPSRate = fpsRate; }
+
+ /// @brief To get with @ref SetFPSRate() changed values.
+ int GetFPSRate() const { return m_cStructure->iFPSRate; }
+
+ /// @brief Height of the stream reported by the demuxer
+ void SetHeight(int height) { m_cStructure->iHeight = height; }
+
+ /// @brief To get with @ref SetHeight() changed values.
+ int GetHeight() const { return m_cStructure->iHeight; }
+
+ /// @brief Width of the stream reported by the demuxer.
+ void SetWidth(int width) { m_cStructure->iWidth = width; }
+
+ /// @brief To get with @ref SetWidth() changed values.
+ int GetWidth() const { return m_cStructure->iWidth; }
+
+ /// @brief Display aspect ratio of the stream.
+ void SetAspect(float aspect) { m_cStructure->fAspect = aspect; }
+
+ /// @brief To get with @ref SetAspect() changed values.
+ float GetAspect() const { return m_cStructure->fAspect; }
+
+ /// @brief Amount of channels.
+ void SetChannels(int channels) { m_cStructure->iChannels = channels; }
+
+ /// @brief To get with @ref SetChannels() changed values.
+ int GetChannels() const { return m_cStructure->iChannels; }
+
+ /// @brief Sample rate.
+ void SetSampleRate(int sampleRate) { m_cStructure->iSampleRate = sampleRate; }
+
+ /// @brief To get with @ref SetSampleRate() changed values.
+ int GetSampleRate() const { return m_cStructure->iSampleRate; }
+
+ /// @brief Block alignment
+ void SetBlockAlign(int blockAlign) { m_cStructure->iBlockAlign = blockAlign; }
+
+ /// @brief To get with @ref SetBlockAlign() changed values.
+ int GetBlockAlign() const { return m_cStructure->iBlockAlign; }
+
+ /// @brief Bit rate.
+ void SetBitRate(int bitRate) { m_cStructure->iBitRate = bitRate; }
+
+ /// @brief To get with @ref SetBitRate() changed values.
+ int GetBitRate() const { return m_cStructure->iBitRate; }
+
+ /// @brief Bits per sample.
+ void SetBitsPerSample(int bitsPerSample) { m_cStructure->iBitsPerSample = bitsPerSample; }
+
+ /// @brief To get with @ref SetBitsPerSample() changed values.
+ int GetBitsPerSample() const { return m_cStructure->iBitsPerSample; }
+ ///@}
+
+private:
+ PVRStreamProperties(const PVR_STREAM_PROPERTIES::PVR_STREAM* type) : CStructHdl(type) {}
+ PVRStreamProperties(PVR_STREAM_PROPERTIES::PVR_STREAM* type) : CStructHdl(type) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamTimes class PVRStreamTimes
+/// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+/// @brief **Times of playing stream (Live TV and recordings)**\n
+/// This class is used to transfer the necessary data when
+/// @ref kodi::addon::PVRStreamProperties::GetStreamTimes is called.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Stream_PVRStreamTimes_Help
+///
+///@{
+class PVRStreamTimes : public CStructHdl<PVRStreamTimes, PVR_STREAM_TIMES>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRStreamTimes() { memset(m_cStructure, 0, sizeof(PVR_STREAM_TIMES)); }
+ PVRStreamTimes(const PVRStreamTimes& type) : CStructHdl(type) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamTimes_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamTimes
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamTimes :</b>
+ /// | Name | Type | Set call | Get call
+ /// |------|------|----------|----------
+ /// | **Start time** | `time_t` | @ref PVRStreamTimes::SetStartTime "SetStartTime" | @ref PVRStreamTimes::GetStartTime "GetStartTime"
+ /// | **PTS start** | `int64_t` | @ref PVRStreamTimes::SetPTSStart "SetPTSStart" | @ref PVRStreamTimes::GetPTSStart "GetPTSStart"
+ /// | **PTS begin** | `int64_t` | @ref PVRStreamTimes::SetPTSBegin "SetPTSBegin" | @ref PVRStreamTimes::GetPTSBegin "GetPTSBegin"
+ /// | **PTS end** | `int64_t` | @ref PVRStreamTimes::SetPTSEnd "SetPTSEnd" | @ref PVRStreamTimes::GetPTSEnd "GetPTSEnd"
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Stream_PVRStreamTimes
+ ///@{
+
+ /// @brief For recordings, this must be zero. For Live TV, this is a reference
+ /// time in units of time_t (UTC) from which time elapsed starts. Ideally start
+ /// of tv show, but can be any other value.
+ void SetStartTime(time_t startTime) { m_cStructure->startTime = startTime; }
+
+ /// @brief To get with @ref SetStartTime() changed values.
+ time_t GetStartTime() const { return m_cStructure->startTime; }
+
+ /// @brief The pts of startTime.
+ void SetPTSStart(int64_t ptsStart) { m_cStructure->ptsStart = ptsStart; }
+
+ /// @brief To get with @ref SetPTSStart() changed values.
+ int64_t GetPTSStart() const { return m_cStructure->ptsStart; }
+
+ /// @brief Earliest pts player can seek back. Value is in micro seconds,
+ /// relative to PTS start. For recordings, this must be zero. For Live TV, this
+ /// must be zero if not timeshifting and must point to begin of the timeshift
+ /// buffer, otherwise.
+ void SetPTSBegin(int64_t ptsBegin) { m_cStructure->ptsBegin = ptsBegin; }
+
+ /// @brief To get with @ref SetPTSBegin() changed values.
+ int64_t GetPTSBegin() const { return m_cStructure->ptsBegin; }
+
+ /// @brief Latest pts player can seek forward. Value is in micro seconds,
+ /// relative to PTS start. For recordings, this must be the total length. For
+ /// Live TV, this must be zero if not timeshifting and must point to end of
+ /// the timeshift buffer, otherwise.
+ void SetPTSEnd(int64_t ptsEnd) { m_cStructure->ptsEnd = ptsEnd; }
+
+ /// @brief To get with @ref SetPTSEnd() changed values.
+ int64_t GetPTSEnd() const { return m_cStructure->ptsEnd; }
+ ///@}
+
+private:
+ PVRStreamTimes(const PVR_STREAM_TIMES* type) : CStructHdl(type) {}
+ PVRStreamTimes(PVR_STREAM_TIMES* type) : CStructHdl(type) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Timers.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Timers.h
new file mode 100644
index 0000000..5ea48fd
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr/Timers.h
@@ -0,0 +1,896 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "General.h"
+#include "../../AddonBase.h"
+#include "../../c-api/addon-instance/pvr.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C++" Definitions group 6 - PVR timers
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimer class PVRTimer
+/// @ingroup cpp_kodi_addon_pvr_Defs_Timer
+/// @brief **PVR add-on timer type**\n
+/// Representation of a timer event.
+///
+/// The related values here are automatically initiated to defaults and need
+/// only be set if supported and used.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Timer_PVRTimer_Help
+///
+///@{
+class PVRTimer : public CStructHdl<PVRTimer, PVR_TIMER>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRTimer()
+ {
+ m_cStructure->iClientIndex = 0;
+ m_cStructure->state = PVR_TIMER_STATE_NEW;
+ m_cStructure->iTimerType = PVR_TIMER_TYPE_NONE;
+ m_cStructure->iParentClientIndex = 0;
+ m_cStructure->iClientChannelUid = PVR_TIMER_VALUE_NOT_AVAILABLE;
+ m_cStructure->startTime = 0;
+ m_cStructure->endTime = 0;
+ m_cStructure->bStartAnyTime = false;
+ m_cStructure->bEndAnyTime = false;
+ m_cStructure->bFullTextEpgSearch = false;
+ m_cStructure->iPriority = PVR_TIMER_VALUE_NOT_AVAILABLE;
+ m_cStructure->iLifetime = PVR_TIMER_VALUE_NOT_AVAILABLE;
+ m_cStructure->iMaxRecordings = PVR_TIMER_VALUE_NOT_AVAILABLE;
+ m_cStructure->iRecordingGroup = 0;
+ m_cStructure->firstDay = 0;
+ m_cStructure->iWeekdays = PVR_WEEKDAY_NONE;
+ m_cStructure->iPreventDuplicateEpisodes = 0;
+ m_cStructure->iEpgUid = 0;
+ m_cStructure->iMarginStart = 0;
+ m_cStructure->iMarginEnd = 0;
+ m_cStructure->iGenreType = PVR_TIMER_VALUE_NOT_AVAILABLE;
+ m_cStructure->iGenreSubType = PVR_TIMER_VALUE_NOT_AVAILABLE;
+ }
+ PVRTimer(const PVRTimer& data) : CStructHdl(data) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimer_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimer
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimer :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Client index** | `unsigned int` | @ref PVRTimer::SetClientIndex "SetClientIndex" | @ref PVRTimer::GetClientIndex "GetClientIndex" | *required to set*
+ /// | **State** | @ref PVR_TIMER_STATE | @ref PVRTimer::SetState "SetState" | @ref PVRTimer::GetState "GetState" | *required to set*
+ /// | **Type** | `unsigned int` | @ref PVRTimer::SetTimerType "SetTimerType" | @ref PVRTimer::GetTimerType "GetTimerType" | *required to set*
+ /// | **Title** | `std::string` | @ref PVRTimer::SetTitle "SetTitle" | @ref PVRTimer::GetTitle "GetTitle" | *required to set*
+ /// | **Parent client index** | `unsigned int` | @ref PVRTimer::SetParentClientIndex "SetParentClientIndex" | @ref PVRTimer::GetParentClientIndex "GetParentClientIndex" | *optional*
+ /// | **Client channel unique identifier** | `int` | @ref PVRTimer::SetClientChannelUid "SetClientChannelUid" | @ref PVRTimer::GetClientChannelUid "GetClientChannelUid" | *optional*
+ /// | **Start time** | `time_t` | @ref PVRTimer::SetStartTime "SetStartTime" | @ref PVRTimer::GetStartTime "GetStartTime" | *optional*
+ /// | **End time** | `time_t` | @ref PVRTimer::SetEndTime "SetEndTime" | @ref PVRTimer::GetEndTime "GetEndTime" | *optional*
+ /// | **Start any time** | `bool` | @ref PVRTimer::SetStartAnyTime "SetStartAnyTime" | @ref PVRTimer::GetStartAnyTime "GetStartAnyTime" | *optional*
+ /// | **End any time** | `bool` | @ref PVRTimer::SetEndAnyTime "SetEndAnyTime" | @ref PVRTimer::GetEndAnyTime "GetEndAnyTime" | *optional*
+ /// | **EPG search string** | `std::string` | @ref PVRTimer::SetEPGSearchString "SetEPGSearchString" | @ref PVRTimer::GetEPGSearchString "GetEPGSearchString" | *optional*
+ /// | **Full text EPG search** | `bool` | @ref PVRTimer::SetFullTextEpgSearch "SetFullTextEpgSearch" | @ref PVRTimer::GetFullTextEpgSearch "GetFullTextEpgSearch" | *optional*
+ /// | **Recording store directory** | `std::string` | @ref PVRTimer::SetDirectory "SetDirectory" | @ref PVRTimer::GetDirectory "GetDirectory" | *optional*
+ /// | **Timer priority** | `int` | @ref PVRTimer::SetPriority "SetPriority" | @ref PVRTimer::GetPriority "GetPriority" | *optional*
+ /// | **Timer lifetime** | `int` | @ref PVRTimer::SetLifetime "SetLifetime" | @ref PVRTimer::GetLifetime "GetLifetime" | *optional*
+ /// | **Max recordings** | `int` | @ref PVRTimer::SetMaxRecordings "SetMaxRecordings" | @ref PVRTimer::GetMaxRecordings "GetMaxRecordings" | *optional*
+ /// | **Recording group** | `unsigned int` | @ref PVRTimer::SetRecordingGroup "SetRecordingGroup" | @ref PVRTimer::GetRecordingGroup "GetRecordingGroup" | *optional*
+ /// | **First start day** | `time_t` | @ref PVRTimer::SetFirstDay "SetFirstDay" | @ref PVRTimer::GetFirstDay "GetFirstDay" | *optional*
+ /// | **Used timer weekdays** | `unsigned int` | @ref PVRTimer::SetWeekdays "SetWeekdays" | @ref PVRTimer::GetWeekdays "GetWeekdays" | *optional*
+ /// | **Prevent duplicate episodes** | `unsigned int` | @ref PVRTimer::SetPreventDuplicateEpisodes "SetPreventDuplicateEpisodes" | @ref PVRTimer::GetPreventDuplicateEpisodes "GetPreventDuplicateEpisodes" | *optional*
+ /// | **EPG unique identifier** | `unsigned int` | @ref PVRTimer::SetEPGUid "SetEPGUid" | @ref PVRTimer::GetEPGUid "GetEPGUid" | *optional*
+ /// | **Margin start** | `unsigned int` | @ref PVRTimer::SetMarginStart "SetMarginStart" | @ref PVRTimer::GetMarginStart "GetMarginStart" | *optional*
+ /// | **Margin end** | `unsigned int` | @ref PVRTimer::SetMarginEnd "SetMarginEnd" | @ref PVRTimer::GetMarginEnd "GetMarginEnd" | *optional*
+ /// | **Genre type** | `int` | @ref PVRTimer::SetGenreType "SetGenreType" | @ref PVRTimer::GetGenreType "GetGenreType" | *optional*
+ /// | **Genre sub type** | `int` | @ref PVRTimer::SetGenreSubType "SetGenreSubType" | @ref PVRTimer::GetGenreSubType "GetGenreSubType" | *optional*
+ /// | **Series link** | `std::string` | @ref PVRTimer::SetSeriesLink "SetSeriesLink" | @ref PVRTimer::GetSeriesLink "GetSeriesLink" | *optional*
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimer
+ ///@{
+
+ /// @brief **required**\n
+ /// The index of this timer given by the client.
+ ///
+ /// @ref PVR_TIMER_NO_CLIENT_INDEX indicates that the index was not yet set
+ /// by the client, for example for new timers created by Kodi and passed the
+ /// first time to the client. A valid index must be greater than
+ /// @ref PVR_TIMER_NO_CLIENT_INDEX.
+ ///
+ void SetClientIndex(unsigned int clientIndex) { m_cStructure->iClientIndex = clientIndex; }
+
+ /// @brief To get with @ref SetClientIndex changed values.
+ unsigned int GetClientIndex() const { return m_cStructure->iClientIndex; }
+
+ /// @brief **required**\n
+ /// The state of this timer.
+ ///
+ /// @note @ref PVR_TIMER_STATE_NEW is default.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRTimer tag;
+ /// tag.SetState(PVR_TIMER_STATE_RECORDING);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetState(PVR_TIMER_STATE state) { m_cStructure->state = state; }
+
+ /// @brief To get with @ref SetState changed values.
+ PVR_TIMER_STATE GetState() const { return m_cStructure->state; }
+
+ /// @brief **required**\n
+ /// The type of this timer.
+ ///
+ /// It is private to the addon and can be freely defined by the addon.
+ /// The value must be greater than @ref PVR_TIMER_TYPE_NONE.
+ ///
+ /// Kodi does not interpret this value (except for checking for @ref PVR_TIMER_TYPE_NONE),
+ /// but will pass the right id to the addon with every @ref PVRTimer instance,
+ /// thus the addon easily can determine the timer type.
+ ///
+ /// @note @ref PVR_TIMER_TYPE_NONE is default.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRTimer tag;
+ /// tag.SetTimerType(123);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetTimerType(unsigned int timerType) { m_cStructure->iTimerType = timerType; }
+
+ /// @brief To get with @ref SetTimerType changed values.
+ unsigned int GetTimerType() const { return m_cStructure->iTimerType; }
+
+ /// @brief **required**\n
+ /// A title for this timer.
+ void SetTitle(const std::string& title)
+ {
+ strncpy(m_cStructure->strTitle, title.c_str(), sizeof(m_cStructure->strTitle) - 1);
+ }
+
+ /// @brief To get with @ref SetTitle changed values.
+ std::string GetTitle() const { return m_cStructure->strTitle; }
+
+ /// @brief **optional**\n
+ /// For timers scheduled by a repeating timer.
+ ///
+ /// The index of the repeating timer that scheduled this timer (it's
+ /// @ref clientIndex value). Use @ref PVR_TIMER_NO_PARENT to indicate that
+ /// this timer was no scheduled by a repeating timer.
+ void SetParentClientIndex(unsigned int parentClientIndex)
+ {
+ m_cStructure->iParentClientIndex = parentClientIndex;
+ }
+
+ /// @brief To get with @ref SetParentClientIndex changed values.
+ unsigned int GetParentClientIndex() const { return m_cStructure->iParentClientIndex; }
+
+ /// @brief **optional**\n
+ /// Unique identifier of the channel to record on.
+ ///
+ /// @ref PVR_TIMER_ANY_CHANNEL will denote "any channel", not a specific one.
+ /// @ref PVR_CHANNEL_INVALID_UID denotes that channel uid is not available.
+ void SetClientChannelUid(int clientChannelUid)
+ {
+ m_cStructure->iClientChannelUid = clientChannelUid;
+ }
+
+ /// @brief To get with @ref SetClientChannelUid changed values
+ int GetClientChannelUid() const { return m_cStructure->iClientChannelUid; }
+
+ /// @brief **optional**\n
+ /// Start time of the recording in UTC.
+ ///
+ /// Instant timers that are sent to the add-on by Kodi will have this value
+ /// set to 0.
+ void SetStartTime(time_t startTime) { m_cStructure->startTime = startTime; }
+
+ /// @brief To get with @ref SetStartTime changed values.
+ time_t GetStartTime() const { return m_cStructure->startTime; }
+
+ /// @brief **optional**\n
+ /// End time of the recording in UTC.
+ void SetEndTime(time_t endTime) { m_cStructure->endTime = endTime; }
+
+ /// @brief To get with @ref SetEndTime changed values.
+ time_t GetEndTime() const { return m_cStructure->endTime; }
+
+ /// @brief **optional**\n
+ /// For EPG based (not Manual) timers indicates startTime does not apply.
+ ///
+ /// Default = false.
+ void SetStartAnyTime(bool startAnyTime) { m_cStructure->bStartAnyTime = startAnyTime; }
+
+ /// @brief To get with @ref SetStartAnyTime changed values.
+ bool GetStartAnyTime() const { return m_cStructure->bStartAnyTime; }
+
+ /// @brief **optional**\n
+ /// For EPG based (not Manual) timers indicates endTime does not apply.
+ ///
+ /// Default = false
+ void SetEndAnyTime(bool endAnyTime) { m_cStructure->bEndAnyTime = endAnyTime; }
+
+ /// @brief To get with @ref SetEndAnyTime changed values.
+ bool GetEndAnyTime() const { return m_cStructure->bEndAnyTime; }
+
+ /// @brief **optional**\n
+ /// A string used to search epg data for repeating epg-based timers.
+ ///
+ /// Format is backend-dependent, for example regexp.
+ void SetEPGSearchString(const std::string& epgSearchString)
+ {
+ strncpy(m_cStructure->strEpgSearchString, epgSearchString.c_str(),
+ sizeof(m_cStructure->strEpgSearchString) - 1);
+ }
+
+ /// @brief To get with @ref SetEPGSearchString changed values
+ std::string GetEPGSearchString() const { return m_cStructure->strEpgSearchString; }
+
+ /// @brief **optional**\n
+ /// Indicates, whether @ref SetEPGSearchString() is to match against the epg
+ /// episode title only or also against "other" epg data (backend-dependent).
+ void SetFullTextEpgSearch(bool fullTextEpgSearch)
+ {
+ m_cStructure->bFullTextEpgSearch = fullTextEpgSearch;
+ }
+
+ /// @brief To get with @ref SetFullTextEpgSearch changed values.
+ bool GetFullTextEpgSearch() const { return m_cStructure->bFullTextEpgSearch; }
+
+ /// @brief **optional**\n
+ /// The (relative) directory where the recording will be stored in.
+ void SetDirectory(const std::string& directory)
+ {
+ strncpy(m_cStructure->strDirectory, directory.c_str(), sizeof(m_cStructure->strDirectory) - 1);
+ }
+
+ /// @brief To get with @ref SetDirectory changed values.
+ std::string GetDirectory() const { return m_cStructure->strDirectory; }
+
+ /// @brief **optional**\n
+ /// The summary for this timer.
+ void SetSummary(const std::string& summary)
+ {
+ strncpy(m_cStructure->strSummary, summary.c_str(), sizeof(m_cStructure->strSummary) - 1);
+ }
+
+ /// @brief To get with @ref SetDirectory changed values.
+ std::string GetSummary() const { return m_cStructure->strSummary; }
+
+ /// @brief **optional**\n
+ /// The priority of this timer.
+ void SetPriority(int priority) { m_cStructure->iPriority = priority; }
+
+ /// @brief To get with @ref SetPriority changed values.
+ int GetPriority() const { return m_cStructure->iPriority; }
+
+ /// @brief **optional**\n
+ /// Lifetime of recordings created by this timer.
+ ///
+ /// Value > 0 days after which recordings will be deleted by the backend, < 0
+ /// addon defined integer list reference, == 0 disabled.
+ void SetLifetime(int priority) { m_cStructure->iLifetime = priority; }
+
+ /// @brief To get with @ref SetLifetime changed values.
+ int GetLifetime() const { return m_cStructure->iLifetime; }
+
+ /// @brief **optional**\n
+ /// Maximum number of recordings this timer shall create.
+ ///
+ /// Value > 0 number of recordings, < 0 addon defined integer list reference, == 0 disabled.
+ void SetMaxRecordings(int maxRecordings) { m_cStructure->iMaxRecordings = maxRecordings; }
+
+ /// @brief To get with @ref SetMaxRecordings changed values.
+ int GetMaxRecordings() const { return m_cStructure->iMaxRecordings; }
+
+ /// @brief **optional**\n
+ /// Integer ref to addon/backend defined list of recording groups.
+ void SetRecordingGroup(unsigned int recordingGroup)
+ {
+ m_cStructure->iRecordingGroup = recordingGroup;
+ }
+
+ /// @brief To get with @ref SetRecordingGroup changed values.
+ unsigned int GetRecordingGroup() const { return m_cStructure->iRecordingGroup; }
+
+ /// @brief **optional**\n
+ /// The first day this timer is active, for repeating timers.
+ void SetFirstDay(time_t firstDay) { m_cStructure->firstDay = firstDay; }
+
+ /// @brief To get with @ref SetFirstDay changed values.
+ time_t GetFirstDay() const { return m_cStructure->firstDay; }
+
+ /// @brief **optional**\n
+ /// Week days, for repeating timers (see
+ /// @ref cpp_kodi_addon_pvr_Defs_Timer_PVR_WEEKDAY "PVR_WEEKDAY_*" constant values)
+ ///
+ /// @note @ref PVR_WEEKDAY_NONE is default.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// kodi::addon::PVRTimer tag;
+ /// tag.SetWeekdays(PVR_WEEKDAY_MONDAY | PVR_WEEKDAY_SATURDAY);
+ /// ...
+ /// ~~~~~~~~~~~~~
+ void SetWeekdays(unsigned int weekdays) { m_cStructure->iWeekdays = weekdays; }
+
+ /// @brief To get with @ref SetFirstDay changed values.
+ unsigned int GetWeekdays() const { return m_cStructure->iWeekdays; }
+
+ /// @brief **optional**\n
+ /// Prevent duplicate episodes.
+ ///
+ /// Should 1 if backend should only record new episodes in case of a repeating
+ /// epg-based timer, 0 if all episodes shall be recorded (no duplicate detection).
+ ///
+ /// Actual algorithm for duplicate detection is defined by the backend.
+ /// Addons may define own values for different duplicate detection
+ /// algorithms, thus this is not just a bool.
+ void SetPreventDuplicateEpisodes(unsigned int preventDuplicateEpisodes)
+ {
+ m_cStructure->iPreventDuplicateEpisodes = preventDuplicateEpisodes;
+ }
+
+ /// @brief To get with @ref SetPreventDuplicateEpisodes changed values.
+ unsigned int GetPreventDuplicateEpisodes() const
+ {
+ return m_cStructure->iPreventDuplicateEpisodes;
+ }
+
+ /// @brief **optional**\n
+ /// EPG event id associated with this timer. Event ids must be unique for a
+ /// channel.
+ ///
+ /// Valid ids must be greater than @ref EPG_TAG_INVALID_UID.
+ void SetEPGUid(unsigned int epgUid) { m_cStructure->iEpgUid = epgUid; }
+
+ /// @brief To get with @ref SetEPGUid changed values.
+ unsigned int GetEPGUid() const { return m_cStructure->iEpgUid; }
+
+ /// @brief **optional**\n
+ /// If set, the backend starts the recording selected minutes before
+ /// @ref SetStartTime.
+ void SetMarginStart(unsigned int marginStart) { m_cStructure->iMarginStart = marginStart; }
+
+ /// @brief To get with @ref SetMarginStart changed values.
+ unsigned int GetMarginStart() const { return m_cStructure->iMarginStart; }
+
+ /// @brief **optional**\n
+ /// If set, the backend ends the recording selected minutes after
+ /// @ref SetEndTime.
+ void SetMarginEnd(unsigned int marginEnd) { m_cStructure->iMarginEnd = marginEnd; }
+
+ /// @brief To get with @ref SetMarginEnd changed values.
+ unsigned int GetMarginEnd() const { return m_cStructure->iMarginEnd; }
+
+ /// @brief **optional**\n
+ /// Genre type.
+ ///
+ /// @copydetails EPG_EVENT_CONTENTMASK
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// kodi::addon::PVRTimer tag;
+ /// tag.SetGenreType(EPG_EVENT_CONTENTMASK_MOVIEDRAMA);
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ /// @note If confirmed that backend brings the types in [ETSI EN 300 468](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf)
+ /// conform values, can be @ref EPG_EVENT_CONTENTMASK ignored and to set here
+ /// with backend value.
+ ///
+ void SetGenreType(int genreType) { m_cStructure->iGenreType = genreType; }
+
+ /// @brief To get with @ref SetGenreType changed values.
+ int GetGenreType() const { return m_cStructure->iGenreType; }
+
+ /// @brief **optional**\n
+ /// Genre sub type.
+ ///
+ /// @copydetails EPG_EVENT_CONTENTMASK
+ ///
+ /// Subtypes groups related to set by @ref SetGenreType:
+ /// | Main genre type | List with available sub genre types
+ /// |-----------------|-----------------------------------------
+ /// | @ref EPG_EVENT_CONTENTMASK_UNDEFINED | Nothing, should be 0
+ /// | @ref EPG_EVENT_CONTENTMASK_MOVIEDRAMA | @ref EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA
+ /// | @ref EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS | @ref EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS
+ /// | @ref EPG_EVENT_CONTENTMASK_SHOW | @ref EPG_EVENT_CONTENTSUBMASK_SHOW
+ /// | @ref EPG_EVENT_CONTENTMASK_SPORTS | @ref EPG_EVENT_CONTENTSUBMASK_SPORTS
+ /// | @ref EPG_EVENT_CONTENTMASK_CHILDRENYOUTH | @ref EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH
+ /// | @ref EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE | @ref EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE
+ /// | @ref EPG_EVENT_CONTENTMASK_ARTSCULTURE | @ref EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE
+ /// | @ref EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS | @ref EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS
+ /// | @ref EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE | @ref EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE
+ /// | @ref EPG_EVENT_CONTENTMASK_LEISUREHOBBIES | @ref EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES
+ /// | @ref EPG_EVENT_CONTENTMASK_SPECIAL | @ref EPG_EVENT_CONTENTSUBMASK_SPECIAL
+ /// | @ref EPG_EVENT_CONTENTMASK_USERDEFINED | Can be defined by you
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// kodi::addon::PVRTimer tag;
+ /// tag.SetGenreType(EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE);
+ /// tag.SetGenreSubType(EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_JAZZ);
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetGenreSubType(int genreSubType) { m_cStructure->iGenreSubType = genreSubType; }
+
+ /// @brief To get with @ref SetGenreType changed values.
+ int GetGenreSubType() const { return m_cStructure->iGenreSubType; }
+
+ /// @brief **optional**\n
+ /// Series link for this timer.
+ ///
+ /// If set for an epg-based timer rule, matching events will be found by
+ /// checking with here, instead of @ref SetTitle() (and @ref SetFullTextEpgSearch()).
+ void SetSeriesLink(const std::string& seriesLink)
+ {
+ strncpy(m_cStructure->strSeriesLink, seriesLink.c_str(),
+ sizeof(m_cStructure->strSeriesLink) - 1);
+ }
+
+ /// @brief To get with @ref SetSeriesLink changed values.
+ std::string GetSeriesLink() const { return m_cStructure->strSeriesLink; }
+ ///@}
+
+private:
+ PVRTimer(const PVR_TIMER* data) : CStructHdl(data) {}
+ PVRTimer(PVR_TIMER* data) : CStructHdl(data) {}
+};
+
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimersResultSet class PVRTimersResultSet
+/// @ingroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimer
+/// @brief **PVR add-on timer transfer class**\n
+/// To transfer the content of @ref kodi::addon::CInstancePVRClient::GetTimers().
+///
+/// @note This becomes only be used on addon call above, not usable outside on
+/// addon itself.
+///@{
+class PVRTimersResultSet
+{
+public:
+ /*! \cond PRIVATE */
+ PVRTimersResultSet() = delete;
+ PVRTimersResultSet(const AddonInstance_PVR* instance, PVR_HANDLE handle)
+ : m_instance(instance), m_handle(handle)
+ {
+ }
+ /*! \endcond */
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimersResultSet
+ ///@{
+
+ /// @brief To add and give content from addon to Kodi on related call.
+ ///
+ /// @param[in] tag The to transferred data.
+ void Add(const kodi::addon::PVRTimer& tag)
+ {
+ m_instance->toKodi->TransferTimerEntry(m_instance->toKodi->kodiInstance, m_handle, tag);
+ }
+
+ ///@}
+
+private:
+ const AddonInstance_PVR* m_instance = nullptr;
+ const PVR_HANDLE m_handle;
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType class PVRTimerType
+/// @ingroup cpp_kodi_addon_pvr_Defs_Timer
+/// @brief **PVR add-on timer type**\n
+/// To define the content of @ref kodi::addon::CInstancePVRClient::GetTimerTypes()
+/// given groups.
+///
+/// ----------------------------------------------------------------------------
+///
+/// @copydetails cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType_Help
+///
+///@{
+class PVRTimerType : public CStructHdl<PVRTimerType, PVR_TIMER_TYPE>
+{
+ friend class CInstancePVRClient;
+
+public:
+ /*! \cond PRIVATE */
+ PVRTimerType()
+ {
+ memset(m_cStructure, 0, sizeof(PVR_TIMER_TYPE));
+ m_cStructure->iPrioritiesDefault = -1;
+ m_cStructure->iLifetimesDefault = -1;
+ m_cStructure->iPreventDuplicateEpisodesDefault = -1;
+ m_cStructure->iRecordingGroupDefault = -1;
+ m_cStructure->iMaxRecordingsDefault = -1;
+ }
+ PVRTimerType(const PVRTimerType& type) : CStructHdl(type) {}
+ /*! \endcond */
+
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType_Help Value Help
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType
+ /// ----------------------------------------------------------------------------
+ ///
+ /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType :</b>
+ /// | Name | Type | Set call | Get call | Usage
+ /// |------|------|----------|----------|-----------
+ /// | **Identifier** | `unsigned int` | @ref PVRTimerType::SetId "SetId" | @ref PVRTimerType::GetId "GetId" | *required to set*
+ /// | **Attributes** | `unsigned int` | @ref PVRTimerType::SetAttributes "SetAttributes" | @ref PVRTimerType::GetAttributes "GetAttributes" | *required to set*
+ /// | **Description** | `std::string` | @ref PVRTimerType::SetDescription "SetDescription" | @ref PVRTimerType::GetDescription "GetDescription" | *optional*
+ /// | | | | | |
+ /// | **Priority selection** | @ref cpp_kodi_addon_pvr_Defs_PVRTypeIntValue "PVRTypeIntValue" | @ref PVRTimerType::SetPriorities "SetPriorities" | @ref PVRTimerType::GetPriorities "GetPriorities" | *optional*
+ /// | **Priority default selection** | `int`| @ref PVRTimerType::SetPrioritiesDefault "SetPrioritiesDefault" | @ref PVRTimerType::GetPrioritiesDefault "GetPrioritiesDefault" | *optional*
+ /// | | | | | |
+ /// | **Lifetime selection** | @ref cpp_kodi_addon_pvr_Defs_PVRTypeIntValue "PVRTypeIntValue" | @ref PVRTimerType::SetLifetimes "SetLifetimes" | @ref PVRTimerType::GetLifetimes "GetLifetimes" | *optional*
+ /// | **Lifetime default selection** | `int`| @ref PVRTimerType::SetLifetimesDefault "SetLifetimesDefault" | @ref PVRTimerType::GetLifetimesDefault "GetLifetimesDefault" | *optional*
+ /// | | | | | |
+ /// | **Prevent duplicate episodes selection** | @ref cpp_kodi_addon_pvr_Defs_PVRTypeIntValue "PVRTypeIntValue" | @ref PVRTimerType::SetPreventDuplicateEpisodes "SetPreventDuplicateEpisodes" | @ref PVRTimerType::GetPreventDuplicateEpisodes "GetPreventDuplicateEpisodes" | *optional*
+ /// | **Prevent duplicate episodes default** | `int`| @ref PVRTimerType::SetPreventDuplicateEpisodesDefault "SetPreventDuplicateEpisodesDefault" | @ref PVRTimerType::GetPreventDuplicateEpisodesDefault "GetPreventDuplicateEpisodesDefault" | *optional*
+ /// | | | | | |
+ /// | **Recording group selection**| @ref cpp_kodi_addon_pvr_Defs_PVRTypeIntValue "PVRTypeIntValue" | @ref PVRTimerType::SetRecordingGroups "SetRecordingGroups" | @ref PVRTimerType::GetRecordingGroups "GetRecordingGroups" | *optional*
+ /// | **Recording group default** | `int`| @ref PVRTimerType::SetRecordingGroupDefault "SetRecordingGroupDefault" | @ref PVRTimerType::GetRecordingGroupDefault "GetRecordingGroupDefault" | *optional*
+ /// | | | | | |
+ /// | **Max recordings selection** | @ref cpp_kodi_addon_pvr_Defs_PVRTypeIntValue "PVRTypeIntValue" | @ref PVRTimerType::SetMaxRecordings "SetMaxRecordings" | @ref PVRTimerType::GetMaxRecordings "GetMaxRecordings" | *optional*
+ /// | **Max recordings default** | `int`| @ref PVRTimerType::SetMaxRecordingsDefault "SetMaxRecordingsDefault" | @ref PVRTimerType::GetMaxRecordingsDefault "GetMaxRecordingsDefault" | *optional*
+ ///
+
+ /// @addtogroup cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType
+ ///@{
+
+ /// @brief **required**\n
+ /// This type's identifier. Ids must be > @ref PVR_TIMER_TYPE_NONE.
+ void SetId(unsigned int id) { m_cStructure->iId = id; }
+
+ /// @brief To get with @ref SetAttributes changed values.
+ unsigned int GetId() const { return m_cStructure->iId; }
+
+ /// @brief **required**\n
+ /// Defines the attributes for this type (@ref cpp_kodi_addon_pvr_Defs_Timer_PVR_TIMER_TYPE "PVR_TIMER_TYPE_*" constants).
+ ///
+ /// To defines the attributes for a type. These values are bit fields that can be
+ /// used together.
+ ///
+ ///--------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRTimerType tag;
+ /// tag.SetAttributes(PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_IS_REPEATING);
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetAttributes(uint64_t attributes) { m_cStructure->iAttributes = attributes; }
+
+ /// @brief To get with @ref SetAttributes changed values.
+ uint64_t GetAttributes() const { return m_cStructure->iAttributes; }
+
+ /// @brief **optional**\n
+ /// A short localized string describing the purpose of the type. (e.g.
+ /// "Any time at this channel if title matches").
+ ///
+ /// If left blank, Kodi will generate a description based on the attributes
+ /// REPEATING and MANUAL. (e.g. "Repeating EPG-based.")
+ void SetDescription(const std::string& description)
+ {
+ strncpy(m_cStructure->strDescription, description.c_str(),
+ sizeof(m_cStructure->strDescription) - 1);
+ }
+
+ /// @brief To get with @ref SetDescription changed values.
+ std::string GetDescription() const { return m_cStructure->strDescription; }
+
+ //----------------------------------------------------------------------------
+
+ /// @brief **optional**\n
+ /// Priority value definitions.
+ ///
+ /// Array containing the possible values for @ref PVRTimer::SetPriority().
+ ///
+ /// @param[in] priorities List of priority values
+ /// @param[in] prioritiesDefault [opt] The default value in list, can also be
+ /// set by @ref SetPrioritiesDefault()
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help
+ void SetPriorities(const std::vector<PVRTypeIntValue>& priorities, int prioritiesDefault = -1)
+ {
+ m_cStructure->iPrioritiesSize = static_cast<unsigned int>(priorities.size());
+ for (unsigned int i = 0;
+ i < m_cStructure->iPrioritiesSize && i < sizeof(m_cStructure->priorities); ++i)
+ {
+ m_cStructure->priorities[i].iValue = priorities[i].GetCStructure()->iValue;
+ strncpy(m_cStructure->priorities[i].strDescription,
+ priorities[i].GetCStructure()->strDescription,
+ sizeof(m_cStructure->priorities[i].strDescription) - 1);
+ }
+ if (prioritiesDefault != -1)
+ m_cStructure->iPrioritiesDefault = prioritiesDefault;
+ }
+
+ /// @brief To get with @ref SetPriorities changed values.
+ std::vector<PVRTypeIntValue> GetPriorities() const
+ {
+ std::vector<PVRTypeIntValue> ret;
+ for (unsigned int i = 0; i < m_cStructure->iPrioritiesSize; ++i)
+ ret.emplace_back(m_cStructure->priorities[i].iValue,
+ m_cStructure->priorities[i].strDescription);
+ return ret;
+ }
+
+ /// @brief **optional**\n
+ /// The default value for @ref PVRTimer::SetPriority().
+ ///
+ /// @note Must be filled if @ref SetPriorities contain values and not
+ /// defined there on second function value.
+ void SetPrioritiesDefault(int prioritiesDefault)
+ {
+ m_cStructure->iPrioritiesDefault = prioritiesDefault;
+ }
+
+ /// @brief To get with @ref SetPrioritiesDefault changed values.
+ int GetPrioritiesDefault() const { return m_cStructure->iPrioritiesDefault; }
+
+ //----------------------------------------------------------------------------
+
+ /// @brief **optional**\n
+ /// Lifetime value definitions.
+ ///
+ /// Array containing the possible values for @ref PVRTimer::SetLifetime().
+ ///
+ /// @param[in] lifetimes List of lifetimes values
+ /// @param[in] lifetimesDefault [opt] The default value in list, can also be
+ /// set by @ref SetLifetimesDefault()
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help
+ void SetLifetimes(const std::vector<PVRTypeIntValue>& lifetimes, int lifetimesDefault = -1)
+ {
+ m_cStructure->iLifetimesSize = static_cast<unsigned int>(lifetimes.size());
+ for (unsigned int i = 0;
+ i < m_cStructure->iLifetimesSize && i < sizeof(m_cStructure->lifetimes); ++i)
+ {
+ m_cStructure->lifetimes[i].iValue = lifetimes[i].GetCStructure()->iValue;
+ strncpy(m_cStructure->lifetimes[i].strDescription,
+ lifetimes[i].GetCStructure()->strDescription,
+ sizeof(m_cStructure->lifetimes[i].strDescription) - 1);
+ }
+ if (lifetimesDefault != -1)
+ m_cStructure->iLifetimesDefault = lifetimesDefault;
+ }
+
+ /// @brief To get with @ref SetLifetimes changed values.
+ std::vector<PVRTypeIntValue> GetLifetimes() const
+ {
+ std::vector<PVRTypeIntValue> ret;
+ for (unsigned int i = 0; i < m_cStructure->iLifetimesSize; ++i)
+ ret.emplace_back(m_cStructure->lifetimes[i].iValue,
+ m_cStructure->lifetimes[i].strDescription);
+ return ret;
+ }
+
+ /// @brief **optional**\n
+ /// The default value for @ref SetLifetimes().
+ ///
+ /// @note Must be filled if @ref SetLifetimes contain values and not
+ /// defined there on second function value.
+ void SetLifetimesDefault(int lifetimesDefault)
+ {
+ m_cStructure->iLifetimesDefault = lifetimesDefault;
+ }
+
+ /// @brief To get with @ref SetLifetimesDefault changed values.
+ int GetLifetimesDefault() const { return m_cStructure->iLifetimesDefault; }
+
+ //----------------------------------------------------------------------------
+
+ /// @brief **optional**\n
+ /// Prevent duplicate episodes value definitions.
+ ///
+ /// Array containing the possible values for @ref PVRTimer::SetPreventDuplicateEpisodes().
+ ///
+ /// @note Must be filled if @ref PVRTimer::SetPreventDuplicateEpisodes() is not empty.
+ ///
+ /// @param[in] preventDuplicateEpisodes List of duplicate episodes values
+ /// @param[in] preventDuplicateEpisodesDefault [opt] The default value in list, can also be
+ /// set by @ref SetPreventDuplicateEpisodesDefault()
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help
+ void SetPreventDuplicateEpisodes(
+ const std::vector<PVRTypeIntValue>& preventDuplicateEpisodes,
+ int preventDuplicateEpisodesDefault = -1)
+ {
+ m_cStructure->iPreventDuplicateEpisodesSize =
+ static_cast<unsigned int>(preventDuplicateEpisodes.size());
+ for (unsigned int i = 0; i < m_cStructure->iPreventDuplicateEpisodesSize &&
+ i < sizeof(m_cStructure->preventDuplicateEpisodes);
+ ++i)
+ {
+ m_cStructure->preventDuplicateEpisodes[i].iValue =
+ preventDuplicateEpisodes[i].GetCStructure()->iValue;
+ strncpy(m_cStructure->preventDuplicateEpisodes[i].strDescription,
+ preventDuplicateEpisodes[i].GetCStructure()->strDescription,
+ sizeof(m_cStructure->preventDuplicateEpisodes[i].strDescription) - 1);
+ }
+ if (preventDuplicateEpisodesDefault != -1)
+ m_cStructure->iPreventDuplicateEpisodesDefault = preventDuplicateEpisodesDefault;
+ }
+
+ /// @brief To get with @ref SetPreventDuplicateEpisodes changed values.
+ std::vector<PVRTypeIntValue> GetPreventDuplicateEpisodes() const
+ {
+ std::vector<PVRTypeIntValue> ret;
+ for (unsigned int i = 0; i < m_cStructure->iPreventDuplicateEpisodesSize; ++i)
+ ret.emplace_back(m_cStructure->preventDuplicateEpisodes[i].iValue,
+ m_cStructure->preventDuplicateEpisodes[i].strDescription);
+ return ret;
+ }
+
+ /// @brief **optional**\n
+ /// The default value for @ref PVRTimer::SetPreventDuplicateEpisodes().
+ ///
+ /// @note Must be filled if @ref SetPreventDuplicateEpisodes contain values and not
+ /// defined there on second function value.
+ void SetPreventDuplicateEpisodesDefault(int preventDuplicateEpisodesDefault)
+ {
+ m_cStructure->iPreventDuplicateEpisodesDefault = preventDuplicateEpisodesDefault;
+ }
+
+ /// @brief To get with @ref SetPreventDuplicateEpisodesDefault changed values.
+ int GetPreventDuplicateEpisodesDefault() const
+ {
+ return m_cStructure->iPreventDuplicateEpisodesDefault;
+ }
+
+ //----------------------------------------------------------------------------
+
+ /// @brief **optional**\n
+ /// Array containing the possible values of @ref PVRTimer::SetRecordingGroup()
+ ///
+ /// @param[in] recordingGroup List of recording group values
+ /// @param[in] recordingGroupDefault [opt] The default value in list, can also be
+ /// set by @ref SetRecordingGroupDefault()
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help
+ void SetRecordingGroups(const std::vector<PVRTypeIntValue>& recordingGroup,
+ int recordingGroupDefault = -1)
+ {
+ m_cStructure->iRecordingGroupSize = static_cast<unsigned int>(recordingGroup.size());
+ for (unsigned int i = 0;
+ i < m_cStructure->iRecordingGroupSize && i < sizeof(m_cStructure->recordingGroup); ++i)
+ {
+ m_cStructure->recordingGroup[i].iValue = recordingGroup[i].GetCStructure()->iValue;
+ strncpy(m_cStructure->recordingGroup[i].strDescription,
+ recordingGroup[i].GetCStructure()->strDescription,
+ sizeof(m_cStructure->recordingGroup[i].strDescription) - 1);
+ }
+ if (recordingGroupDefault != -1)
+ m_cStructure->iRecordingGroupDefault = recordingGroupDefault;
+ }
+
+ /// @brief To get with @ref SetRecordingGroups changed values
+ std::vector<PVRTypeIntValue> GetRecordingGroups() const
+ {
+ std::vector<PVRTypeIntValue> ret;
+ for (unsigned int i = 0; i < m_cStructure->iRecordingGroupSize; ++i)
+ ret.emplace_back(m_cStructure->recordingGroup[i].iValue,
+ m_cStructure->recordingGroup[i].strDescription);
+ return ret;
+ }
+
+ /// @brief **optional**\n
+ /// The default value for @ref PVRTimer::SetRecordingGroup().
+ ///
+ /// @note Must be filled if @ref SetRecordingGroups contain values and not
+ /// defined there on second function value.
+ void SetRecordingGroupDefault(int recordingGroupDefault)
+ {
+ m_cStructure->iRecordingGroupDefault = recordingGroupDefault;
+ }
+
+ /// @brief To get with @ref SetRecordingGroupDefault changed values
+ int GetRecordingGroupDefault() const { return m_cStructure->iRecordingGroupDefault; }
+
+ //----------------------------------------------------------------------------
+
+ /// @brief **optional**\n
+ /// Array containing the possible values of @ref PVRTimer::SetMaxRecordings().
+ ///
+ /// @param[in] maxRecordings List of lifetimes values
+ /// @param[in] maxRecordingsDefault [opt] The default value in list, can also be
+ /// set by @ref SetMaxRecordingsDefault()
+ ///
+ /// --------------------------------------------------------------------------
+ ///
+ /// @copydetails cpp_kodi_addon_pvr_Defs_PVRTypeIntValue_Help
+ void SetMaxRecordings(const std::vector<PVRTypeIntValue>& maxRecordings,
+ int maxRecordingsDefault = -1)
+ {
+ m_cStructure->iMaxRecordingsSize = static_cast<unsigned int>(maxRecordings.size());
+ for (unsigned int i = 0;
+ i < m_cStructure->iMaxRecordingsSize && i < sizeof(m_cStructure->maxRecordings); ++i)
+ {
+ m_cStructure->maxRecordings[i].iValue = maxRecordings[i].GetCStructure()->iValue;
+ strncpy(m_cStructure->maxRecordings[i].strDescription,
+ maxRecordings[i].GetCStructure()->strDescription,
+ sizeof(m_cStructure->maxRecordings[i].strDescription) - 1);
+ }
+ if (maxRecordingsDefault != -1)
+ m_cStructure->iMaxRecordingsDefault = maxRecordingsDefault;
+ }
+
+ /// @brief To get with @ref SetMaxRecordings changed values
+ std::vector<PVRTypeIntValue> GetMaxRecordings() const
+ {
+ std::vector<PVRTypeIntValue> ret;
+ for (unsigned int i = 0; i < m_cStructure->iMaxRecordingsSize; ++i)
+ ret.emplace_back(m_cStructure->maxRecordings[i].iValue,
+ m_cStructure->maxRecordings[i].strDescription);
+ return ret;
+ }
+
+ /// @brief **optional**\n
+ /// The default value for @ref SetMaxRecordings().
+ ///
+ /// Can be set with here if on @ref SetMaxRecordings not given as second value.
+ void SetMaxRecordingsDefault(int maxRecordingsDefault)
+ {
+ m_cStructure->iMaxRecordingsDefault = maxRecordingsDefault;
+ }
+
+ /// @brief To get with @ref SetMaxRecordingsDefault changed values
+ int GetMaxRecordingsDefault() const { return m_cStructure->iMaxRecordingsDefault; }
+ ///@}
+
+private:
+ PVRTimerType(const PVR_TIMER_TYPE* type) : CStructHdl(type) {}
+ PVRTimerType(PVR_TIMER_TYPE* type) : CStructHdl(type) {}
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace addon */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/CMakeLists.txt
new file mode 100644
index 0000000..a7dd1d3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ addon_base.h
+ audio_engine.h
+ filesystem.h
+ general.h
+ network.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/CMakeLists.txt
new file mode 100644
index 0000000..52670eb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ audiodecoder.h
+ audioencoder.h
+ game.h
+ imagedecoder.h
+ inputstream.h
+ peripheral.h
+ pvr.h
+ screensaver.h
+ vfs.h
+ video_codec.h
+ visualization.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_addon-instance)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audiodecoder.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audiodecoder.h
new file mode 100644
index 0000000..c75ec48
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audiodecoder.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_AUDIODECODER_H
+#define C_API_ADDONINSTANCE_AUDIODECODER_H
+
+#include "../addon_base.h"
+#include "../audio_engine.h"
+
+//============================================================================
+/// @ingroup cpp_kodi_addon_audiodecoder_Defs
+/// @brief Identifier which is attached to stream files and with defined names
+/// in addon.xml (`name="???"`) if addon supports "tracks" (set in addon.xml
+/// `tracks="true"`).
+///
+/// @note This macro is largely unnecessary to use directly on the addon,
+/// addon can use the @ref KODI_ADDON_AUDIODECODER_GET_TRACK_EXT around its
+/// associated name.
+///
+///@{
+#define KODI_ADDON_AUDIODECODER_TRACK_EXT "_adecstrm"
+///@}
+//----------------------------------------------------------------------------
+
+//============================================================================
+/// @ingroup cpp_kodi_addon_audiodecoder_Defs
+/// @brief Macro to get file extension to track supported files.
+///
+/// This macro can be used if `tracks="true"` is set in addon.xml, in this
+/// case the addon.xml field `name="???"` is used to identify stream.
+/// Which must then also be used for here.
+///
+///@{
+#define KODI_ADDON_AUDIODECODER_GET_TRACK_EXT(name) "." name KODI_ADDON_AUDIODECODER_TRACK_EXT
+///@}
+//----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef KODI_ADDON_INSTANCE_HDL KODI_ADDON_AUDIODECODER_HDL;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_audiodecoder_Defs_AUDIODECODER_READ_RETURN enum AUDIODECODER_READ_RETURN
+ /// @ingroup cpp_kodi_addon_audiodecoder_Defs
+ /// @brief **Return value about** @ref kodi::addon::CInstanceAudioDecoder::ReadPCM()
+ ///
+ /// Possible values are:
+ /// | Value | enum | Description
+ /// |:-----:|:-------------------------------|:--------------------------
+ /// | 0 | @ref AUDIODECODER_READ_SUCCESS | on success
+ /// | -1 | @ref AUDIODECODER_READ_EOF | on end of stream
+ /// | 1 | @ref AUDIODECODER_READ_ERROR | on failure
+ ///
+ ///@{
+ typedef enum AUDIODECODER_READ_RETURN
+ {
+ /// @brief On end of stream
+ AUDIODECODER_READ_EOF = -1,
+
+ /// @brief On success
+ AUDIODECODER_READ_SUCCESS = 0,
+
+ /// @brief On failure
+ AUDIODECODER_READ_ERROR = 1
+ } AUDIODECODER_READ_RETURN;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ struct KODI_ADDON_AUDIODECODER_INFO_TAG
+ {
+ char* title;
+ char* artist;
+ char* album;
+ char* album_artist;
+ char* media_type;
+ char* genre;
+ int duration;
+ int track;
+ int disc;
+ char* disc_subtitle;
+ int disc_total;
+ char* release_date;
+ char* lyrics;
+ int samplerate;
+ int channels;
+ int bitrate;
+ char* comment;
+ char* cover_art_path;
+ char* cover_art_mem_mimetype;
+ uint8_t* cover_art_mem;
+ size_t cover_art_mem_size;
+ };
+
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIODECODER_SUPPORTS_FILE_V1)(
+ const KODI_ADDON_AUDIODECODER_HDL hdl, const char* file);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIODECODER_INIT_V1)(
+ const KODI_ADDON_AUDIODECODER_HDL hdl,
+ const char* file,
+ unsigned int filecache,
+ int* channels,
+ int* samplerate,
+ int* bitspersample,
+ int64_t* totaltime,
+ int* bitrate,
+ enum AudioEngineDataFormat* format,
+ enum AudioEngineChannel info[AUDIOENGINE_CH_MAX]);
+ typedef int(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIODECODER_READ_PCM_V1)(
+ const KODI_ADDON_AUDIODECODER_HDL hdl, uint8_t* buffer, size_t size, size_t* actualsize);
+ typedef int64_t(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIODECODER_SEEK_V1)(
+ const KODI_ADDON_AUDIODECODER_HDL hdl, int64_t time);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIODECODER_READ_TAG_V1)(
+ const KODI_ADDON_AUDIODECODER_HDL hdl,
+ const char* file,
+ struct KODI_ADDON_AUDIODECODER_INFO_TAG* tag);
+ typedef int(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIODECODER_TRACK_COUNT_V1)(
+ const KODI_ADDON_AUDIODECODER_HDL hdl, const char* file);
+
+ typedef struct AddonToKodiFuncTable_AudioDecoder
+ {
+ KODI_HANDLE kodiInstance;
+ } AddonToKodiFuncTable_AudioDecoder;
+
+ typedef struct KodiToAddonFuncTable_AudioDecoder
+ {
+ PFN_KODI_ADDON_AUDIODECODER_SUPPORTS_FILE_V1 supports_file;
+ PFN_KODI_ADDON_AUDIODECODER_INIT_V1 init;
+ PFN_KODI_ADDON_AUDIODECODER_READ_PCM_V1 read_pcm;
+ PFN_KODI_ADDON_AUDIODECODER_SEEK_V1 seek;
+ PFN_KODI_ADDON_AUDIODECODER_READ_TAG_V1 read_tag;
+ PFN_KODI_ADDON_AUDIODECODER_TRACK_COUNT_V1 track_count;
+ } KodiToAddonFuncTable_AudioDecoder;
+
+ typedef struct AddonInstance_AudioDecoder
+ {
+ struct AddonToKodiFuncTable_AudioDecoder* toKodi;
+ struct KodiToAddonFuncTable_AudioDecoder* toAddon;
+ } AddonInstance_AudioDecoder;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_AUDIODECODER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audioencoder.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audioencoder.h
new file mode 100644
index 0000000..220e4e4
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/audioencoder.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_AUDIO_ENCODER_H
+#define C_API_ADDONINSTANCE_AUDIO_ENCODER_H
+
+#include "../addon_base.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef KODI_ADDON_INSTANCE_HDL KODI_ADDON_AUDIOENCODER_HDL;
+
+ struct KODI_ADDON_AUDIOENCODER_INFO_TAG
+ {
+ const char* title;
+ const char* artist;
+ const char* album;
+ const char* album_artist;
+ const char* media_type;
+ const char* genre;
+ int duration;
+ int track;
+ int disc;
+ const char* disc_subtitle;
+ int disc_total;
+ const char* release_date;
+ const char* lyrics;
+ int samplerate;
+ int channels;
+ int bits_per_sample;
+ int track_length;
+ const char* comment;
+ };
+
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIOENCODER_START_V1)(
+ KODI_ADDON_AUDIOENCODER_HDL hdl, const struct KODI_ADDON_AUDIOENCODER_INFO_TAG* tag);
+ typedef ssize_t(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIOENCODER_ENCODE_V1)(
+ KODI_ADDON_AUDIOENCODER_HDL hdl, const uint8_t* pbt_stream, size_t num_bytes_read);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_AUDIOENCODER_FINISH_V1)(
+ KODI_ADDON_AUDIOENCODER_HDL hdl);
+
+ typedef struct AddonToKodiFuncTable_AudioEncoder
+ {
+ KODI_HANDLE kodiInstance;
+ ssize_t (*write)(KODI_HANDLE kodiInstance, const uint8_t* data, size_t len);
+ ssize_t (*seek)(KODI_HANDLE kodiInstance, ssize_t pos, int whence);
+ } AddonToKodiFuncTable_AudioEncoder;
+
+ typedef struct KodiToAddonFuncTable_AudioEncoder
+ {
+ PFN_KODI_ADDON_AUDIOENCODER_START_V1 start;
+ PFN_KODI_ADDON_AUDIOENCODER_ENCODE_V1 encode;
+ PFN_KODI_ADDON_AUDIOENCODER_FINISH_V1 finish;
+ } KodiToAddonFuncTable_AudioEncoder;
+
+ typedef struct AddonInstance_AudioEncoder
+ {
+ struct AddonToKodiFuncTable_AudioEncoder* toKodi;
+ struct KodiToAddonFuncTable_AudioEncoder* toAddon;
+ } AddonInstance_AudioEncoder;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_AUDIO_ENCODER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/game.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/game.h
new file mode 100644
index 0000000..e0bbf94
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/game.h
@@ -0,0 +1,1235 @@
+/*
+ * Copyright (C) 2014-2020 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_GAME_H
+#define C_API_ADDONINSTANCE_GAME_H
+
+#include "../addon_base.h"
+
+#include <stddef.h> /* size_t */
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon_game_Defs
+/// @brief **Port ID used when topology is unknown**
+#define DEFAULT_PORT_ID "1"
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **Game add-on error codes**
+ ///
+ /// Used as return values on most Game related functions.
+ ///
+ typedef enum GAME_ERROR
+ {
+ /// @brief no error occurred
+ GAME_ERROR_NO_ERROR,
+
+ /// @brief an unknown error occurred
+ GAME_ERROR_UNKNOWN,
+
+ /// @brief the method that the frontend called is not implemented
+ GAME_ERROR_NOT_IMPLEMENTED,
+
+ /// @brief the command was rejected by the game client
+ GAME_ERROR_REJECTED,
+
+ /// @brief the parameters of the method that was called are invalid for this operation
+ GAME_ERROR_INVALID_PARAMETERS,
+
+ /// @brief the command failed
+ GAME_ERROR_FAILED,
+
+ /// @brief no game is loaded
+ GAME_ERROR_NOT_LOADED,
+
+ /// @brief game requires restricted resources
+ GAME_ERROR_RESTRICTED,
+ } GAME_ERROR;
+ //----------------------------------------------------------------------------
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_AudioStream 1. Audio stream
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **The for Audio stream used data system**
+ ///
+ /// Used to give Addon currently used audio stream configuration on Kodi and
+ /// arrays to give related data to Kodi on callbacks.
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief **Stream Format**
+ ///
+ /// From Kodi requested specified audio sample format.
+ ///
+ typedef enum GAME_PCM_FORMAT
+ {
+ GAME_PCM_FORMAT_UNKNOWN,
+
+ /// @brief S16NE sample format
+ GAME_PCM_FORMAT_S16NE,
+ } GAME_PCM_FORMAT;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Audio channel**
+ ///
+ /// Channel identification flags.
+ ///
+ typedef enum GAME_AUDIO_CHANNEL
+ {
+ /// @brief Channel list terminator
+ GAME_CH_NULL,
+
+ /// @brief Channel front left
+ GAME_CH_FL,
+
+ /// @brief Channel front right
+ GAME_CH_FR,
+
+ /// @brief Channel front center
+ GAME_CH_FC,
+
+ /// @brief Channel Low Frequency Effects / Subwoofer
+ GAME_CH_LFE,
+
+ /// @brief Channel back left
+ GAME_CH_BL,
+
+ /// @brief Channel back right
+ GAME_CH_BR,
+
+ /// @brief Channel front left over center
+ GAME_CH_FLOC,
+
+ /// @brief Channel front right over center
+ GAME_CH_FROC,
+
+ /// @brief Channel back center
+ GAME_CH_BC,
+
+ /// @brief Channel surround/side left
+ GAME_CH_SL,
+
+ /// @brief Channel surround/side right
+ GAME_CH_SR,
+
+ /// @brief Channel top front left
+ GAME_CH_TFL,
+
+ /// @brief Channel top front right
+ GAME_CH_TFR,
+
+ /// @brief Channel top front center
+ GAME_CH_TFC,
+
+ /// @brief Channel top center
+ GAME_CH_TC,
+
+ /// @brief Channel top back left
+ GAME_CH_TBL,
+
+ /// @brief Channel top back right
+ GAME_CH_TBR,
+
+ /// @brief Channel top back center
+ GAME_CH_TBC,
+
+ /// @brief Channel bacl left over center
+ GAME_CH_BLOC,
+
+ /// @brief Channel back right over center
+ GAME_CH_BROC,
+ } GAME_AUDIO_CHANNEL;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Game audio stream properties**
+ ///
+ /// Used by Kodi to pass the currently required audio stream settings to the addon
+ ///
+ typedef struct game_stream_audio_properties
+ {
+ GAME_PCM_FORMAT format;
+ const GAME_AUDIO_CHANNEL* channel_map;
+ } ATTR_PACKED game_stream_audio_properties;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Audio stream packet**
+ ///
+ /// This packet contains audio stream data passed to Kodi.
+ ///
+ typedef struct game_stream_audio_packet
+ {
+ /// @brief Pointer for audio stream data given to Kodi
+ const uint8_t* data;
+
+ /// @brief Size of data array
+ size_t size;
+ } ATTR_PACKED game_stream_audio_packet;
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_VideoStream 2. Video stream
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **The for Video stream used data system**
+ ///
+ /// Used to give Addon currently used video stream configuration on Kodi and
+ /// arrays to give related data to Kodi on callbacks.
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief **Pixel format**
+ ///
+ /// From Kodi requested specified video RGB color model format.
+ ///
+ typedef enum GAME_PIXEL_FORMAT
+ {
+ GAME_PIXEL_FORMAT_UNKNOWN,
+
+ /// @brief 0RGB8888 Format
+ GAME_PIXEL_FORMAT_0RGB8888,
+
+ /// @brief RGB565 Format
+ GAME_PIXEL_FORMAT_RGB565,
+
+ /// @brief 0RGB1555 Format
+ GAME_PIXEL_FORMAT_0RGB1555,
+ } GAME_PIXEL_FORMAT;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Video rotation position**
+ ///
+ /// To define position how video becomes shown.
+ ///
+ typedef enum GAME_VIDEO_ROTATION
+ {
+ /// @brief 0° and Without rotation
+ GAME_VIDEO_ROTATION_0,
+
+ /// @brief rotate 90° counterclockwise
+ GAME_VIDEO_ROTATION_90_CCW,
+
+ /// @brief rotate 180° counterclockwise
+ GAME_VIDEO_ROTATION_180_CCW,
+
+ /// @brief rotate 270° counterclockwise
+ GAME_VIDEO_ROTATION_270_CCW,
+ } GAME_VIDEO_ROTATION;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Game video stream properties**
+ ///
+ /// Used by Kodi to pass the currently required video stream settings to the addon
+ ///
+ typedef struct game_stream_video_properties
+ {
+ /// @brief The stream's pixel format
+ GAME_PIXEL_FORMAT format;
+
+ /// @brief The nominal used width
+ unsigned int nominal_width;
+
+ /// @brief The nominal used height
+ unsigned int nominal_height;
+
+ /// @brief The maximal used width
+ unsigned int max_width;
+
+ /// @brief The maximal used height
+ unsigned int max_height;
+
+ /// @brief On video stream used aspect ration
+ ///
+ /// @note If aspect_ratio is <= 0.0, an aspect ratio of nominal_width / nominal_height is assumed
+ float aspect_ratio;
+ } ATTR_PACKED game_stream_video_properties;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Video stream packet**
+ ///
+ /// This packet contains video stream data passed to Kodi.
+ ///
+ typedef struct game_stream_video_packet
+ {
+ /// @brief Video height
+ unsigned int width;
+
+ /// @brief Video width
+ unsigned int height;
+
+ /// @brief Width @ref GAME_VIDEO_ROTATION defined rotation angle.
+ GAME_VIDEO_ROTATION rotation;
+
+ /// @brief Pointer for video stream data given to Kodi
+ const uint8_t* data;
+
+ /// @brief Size of data array
+ size_t size;
+ } ATTR_PACKED game_stream_video_packet;
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_HardwareFramebuffer 3. Hardware framebuffer stream
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **Hardware framebuffer stream data**
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief **Hardware framebuffer type**
+ ///
+ typedef enum GAME_HW_CONTEXT_TYPE
+ {
+ /// @brief None context
+ GAME_HW_CONTEXT_NONE,
+
+ /// @brief OpenGL 2.x. Driver can choose to use latest compatibility context
+ GAME_HW_CONTEXT_OPENGL,
+
+ /// @brief OpenGL ES 2.0
+ GAME_HW_CONTEXT_OPENGLES2,
+
+ /// @brief Modern desktop core GL context. Use major/minor fields to set GL version
+ GAME_HW_CONTEXT_OPENGL_CORE,
+
+ /// @brief OpenGL ES 3.0
+ GAME_HW_CONTEXT_OPENGLES3,
+
+ /// @brief OpenGL ES 3.1+. Set major/minor fields.
+ GAME_HW_CONTEXT_OPENGLES_VERSION,
+
+ /// @brief Vulkan
+ GAME_HW_CONTEXT_VULKAN
+ } GAME_HW_CONTEXT_TYPE;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Hardware framebuffer properties**
+ ///
+ typedef struct game_stream_hw_framebuffer_properties
+ {
+ /// @brief The API to use.
+ ///
+ GAME_HW_CONTEXT_TYPE context_type;
+
+ /// @brief Set if render buffers should have depth component attached.
+ ///
+ /// @todo: Obsolete
+ ///
+ bool depth;
+
+ /// @brief Set if stencil buffers should be attached.
+ ///
+ /// If depth and stencil are true, a packed 24/8 buffer will be added.
+ /// Only attaching stencil is invalid and will be ignored.
+ ///
+ /// @todo: Obsolete.
+ ///
+ bool stencil;
+
+ /// @brief Use conventional bottom-left origin convention.
+ ///
+ /// If false, standard top-left origin semantics are used.
+ ///
+ /// @todo: Move to GL specific interface
+ ///
+ bool bottom_left_origin;
+
+ /// @brief Major version number for core GL context or GLES 3.1+.
+ unsigned int version_major;
+
+ /// @brief Minor version number for core GL context or GLES 3.1+.
+ unsigned int version_minor;
+
+ /// @brief If this is true, the frontend will go very far to avoid resetting context
+ /// in scenarios like toggling fullscreen, etc.
+ ///
+ /// @todo: Obsolete? Maybe frontend should just always assume this...
+ ///
+ /// The reset callback might still be called in extreme situations such as if
+ /// the context is lost beyond recovery.
+ ///
+ /// For optimal stability, set this to false, and allow context to be reset at
+ /// any time.
+ ///
+ bool cache_context;
+
+ /// @brief Creates a debug context.
+ bool debug_context;
+ } ATTR_PACKED game_stream_hw_framebuffer_properties;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Hardware framebuffer buffer**
+ ///
+ typedef struct game_stream_hw_framebuffer_buffer
+ {
+ /// @brief
+ uintptr_t framebuffer;
+ } ATTR_PACKED game_stream_hw_framebuffer_buffer;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Hardware framebuffer packet**
+ ///
+ typedef struct game_stream_hw_framebuffer_packet
+ {
+ /// @brief
+ uintptr_t framebuffer;
+ } ATTR_PACKED game_stream_hw_framebuffer_packet;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Hardware framebuffer process function address**
+ ///
+ typedef void (*game_proc_address_t)(void);
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_SoftwareFramebuffer 4. Software framebuffer stream
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **Software framebuffer stream data**
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief **Game video stream properties**
+ ///
+ /// Used by Kodi to pass the currently required video stream settings to the addon
+ ///
+ typedef game_stream_video_properties game_stream_sw_framebuffer_properties;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Hardware framebuffer type**
+ ///
+ typedef struct game_stream_sw_framebuffer_buffer
+ {
+ GAME_PIXEL_FORMAT format;
+ uint8_t* data;
+ size_t size;
+ } ATTR_PACKED game_stream_sw_framebuffer_buffer;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Video stream packet**
+ ///
+ /// This packet contains video stream data passed to Kodi.
+ ///
+ typedef game_stream_video_packet game_stream_sw_framebuffer_packet;
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_StreamTypes 5. Stream types
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **Stream types data**
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief **Game stream types**
+ ///
+ typedef enum GAME_STREAM_TYPE
+ {
+ /// @brief Unknown
+ GAME_STREAM_UNKNOWN,
+
+ /// @brief Audio stream
+ GAME_STREAM_AUDIO,
+
+ /// @brief Video stream
+ GAME_STREAM_VIDEO,
+
+ /// @brief Hardware framebuffer
+ GAME_STREAM_HW_FRAMEBUFFER,
+
+ /// @brief Software framebuffer
+ GAME_STREAM_SW_FRAMEBUFFER,
+ } GAME_STREAM_TYPE;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Immutable stream metadata**
+ ///
+ /// This metadata is provided when the stream is opened. If any stream
+ /// properties change, a new stream must be opened.
+ ///
+ typedef struct game_stream_properties
+ {
+ /// @brief
+ GAME_STREAM_TYPE type;
+ union
+ {
+ /// @brief
+ game_stream_audio_properties audio;
+
+ /// @brief
+ game_stream_video_properties video;
+
+ /// @brief
+ game_stream_hw_framebuffer_properties hw_framebuffer;
+
+ /// @brief
+ game_stream_sw_framebuffer_properties sw_framebuffer;
+ };
+ } ATTR_PACKED game_stream_properties;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Stream buffers for hardware rendering and zero-copy support**
+ ///
+ typedef struct game_stream_buffer
+ {
+ /// @brief
+ GAME_STREAM_TYPE type;
+ union
+ {
+ /// @brief
+ game_stream_hw_framebuffer_buffer hw_framebuffer;
+
+ /// @brief
+ game_stream_sw_framebuffer_buffer sw_framebuffer;
+ };
+ } ATTR_PACKED game_stream_buffer;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Stream packet and ephemeral metadata**
+ ///
+ /// This packet contains stream data and accompanying metadata. The metadata
+ /// is ephemeral, meaning it only applies to the current packet and can change
+ /// from packet to packet in the same stream.
+ ///
+ typedef struct game_stream_packet
+ {
+ /// @brief
+ GAME_STREAM_TYPE type;
+ union
+ {
+ /// @brief
+ game_stream_audio_packet audio;
+
+ /// @brief
+ game_stream_video_packet video;
+
+ /// @brief
+ game_stream_hw_framebuffer_packet hw_framebuffer;
+
+ /// @brief
+ game_stream_sw_framebuffer_packet sw_framebuffer;
+ };
+ } ATTR_PACKED game_stream_packet;
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_GameTypes 6. Game types
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **Game types data**
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief **Game reguin definition**
+ ///
+ /// Returned from game_get_region()
+ typedef enum GAME_REGION
+ {
+ /// @brief Game region unknown
+ GAME_REGION_UNKNOWN,
+
+ /// @brief Game region NTSC
+ GAME_REGION_NTSC,
+
+ /// @brief Game region PAL
+ GAME_REGION_PAL,
+ } GAME_REGION;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Special game types passed into game_load_game_special().**
+ ///
+ /// @remark Only used when multiple ROMs are required.
+ ///
+ typedef enum SPECIAL_GAME_TYPE
+ {
+ /// @brief Game Type BSX
+ SPECIAL_GAME_TYPE_BSX,
+
+ /// @brief Game Type BSX slotted
+ SPECIAL_GAME_TYPE_BSX_SLOTTED,
+
+ /// @brief Game Type sufami turbo
+ SPECIAL_GAME_TYPE_SUFAMI_TURBO,
+
+ /// @brief Game Type super game boy
+ SPECIAL_GAME_TYPE_SUPER_GAME_BOY,
+ } SPECIAL_GAME_TYPE;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Game Memory**
+ ///
+ typedef enum GAME_MEMORY
+ {
+ /// @brief Passed to game_get_memory_data/size(). If the memory type doesn't apply
+ /// to the implementation NULL/0 can be returned.
+ GAME_MEMORY_MASK = 0xff,
+
+ /// @brief Regular save ram.
+ ///
+ /// This ram is usually found on a game cartridge, backed
+ /// up by a battery. If save game data is too complex for a single memory
+ /// buffer, the SYSTEM_DIRECTORY environment callback can be used.
+ GAME_MEMORY_SAVE_RAM = 0,
+
+ /// @brief Some games have a built-in clock to keep track of time.
+ ///
+ /// This memory is usually just a couple of bytes to keep track of time.
+ GAME_MEMORY_RTC = 1,
+
+ /// @brief System ram lets a frontend peek into a game systems main RAM
+ GAME_MEMORY_SYSTEM_RAM = 2,
+
+ /// @brief Video ram lets a frontend peek into a game systems video RAM (VRAM)
+ GAME_MEMORY_VIDEO_RAM = 3,
+
+ /// @brief Special memory type
+ GAME_MEMORY_SNES_BSX_RAM = ((1 << 8) | GAME_MEMORY_SAVE_RAM),
+
+ /// @brief Special memory type
+ GAME_MEMORY_SNES_BSX_PRAM = ((2 << 8) | GAME_MEMORY_SAVE_RAM),
+
+ /// @brief Special memory type
+ GAME_MEMORY_SNES_SUFAMI_TURBO_A_RAM = ((3 << 8) | GAME_MEMORY_SAVE_RAM),
+
+ /// @brief Special memory type
+ GAME_MEMORY_SNES_SUFAMI_TURBO_B_RAM = ((4 << 8) | GAME_MEMORY_SAVE_RAM),
+
+ /// @brief Special memory type
+ GAME_MEMORY_SNES_GAME_BOY_RAM = ((5 << 8) | GAME_MEMORY_SAVE_RAM),
+
+ /// @brief Special memory type
+ GAME_MEMORY_SNES_GAME_BOY_RTC = ((6 << 8) | GAME_MEMORY_RTC),
+ } GAME_MEMORY;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **ID values for SIMD CPU features**
+ typedef enum GAME_SIMD
+ {
+ /// @brief SIMD CPU SSE
+ GAME_SIMD_SSE = (1 << 0),
+
+ /// @brief SIMD CPU SSE2
+ GAME_SIMD_SSE2 = (1 << 1),
+
+ /// @brief SIMD CPU VMX
+ GAME_SIMD_VMX = (1 << 2),
+
+ /// @brief SIMD CPU VMX128
+ GAME_SIMD_VMX128 = (1 << 3),
+
+ /// @brief SIMD CPU AVX
+ GAME_SIMD_AVX = (1 << 4),
+
+ /// @brief SIMD CPU NEON
+ GAME_SIMD_NEON = (1 << 5),
+
+ /// @brief SIMD CPU SSE3
+ GAME_SIMD_SSE3 = (1 << 6),
+
+ /// @brief SIMD CPU SSSE3
+ GAME_SIMD_SSSE3 = (1 << 7),
+
+ /// @brief SIMD CPU MMX
+ GAME_SIMD_MMX = (1 << 8),
+
+ /// @brief SIMD CPU MMXEXT
+ GAME_SIMD_MMXEXT = (1 << 9),
+
+ /// @brief SIMD CPU SSE4
+ GAME_SIMD_SSE4 = (1 << 10),
+
+ /// @brief SIMD CPU SSE42
+ GAME_SIMD_SSE42 = (1 << 11),
+
+ /// @brief SIMD CPU AVX2
+ GAME_SIMD_AVX2 = (1 << 12),
+
+ /// @brief SIMD CPU VFPU
+ GAME_SIMD_VFPU = (1 << 13),
+ } GAME_SIMD;
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_InputTypes 7. Input types
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **Input types**
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief
+ typedef enum GAME_INPUT_EVENT_SOURCE
+ {
+ /// @brief
+ GAME_INPUT_EVENT_DIGITAL_BUTTON,
+
+ /// @brief
+ GAME_INPUT_EVENT_ANALOG_BUTTON,
+
+ /// @brief
+ GAME_INPUT_EVENT_AXIS,
+
+ /// @brief
+ GAME_INPUT_EVENT_ANALOG_STICK,
+
+ /// @brief
+ GAME_INPUT_EVENT_ACCELEROMETER,
+
+ /// @brief
+ GAME_INPUT_EVENT_KEY,
+
+ /// @brief
+ GAME_INPUT_EVENT_RELATIVE_POINTER,
+
+ /// @brief
+ GAME_INPUT_EVENT_ABSOLUTE_POINTER,
+
+ /// @brief
+ GAME_INPUT_EVENT_MOTOR,
+ } GAME_INPUT_EVENT_SOURCE;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef enum GAME_KEY_MOD
+ {
+ /// @brief
+ GAME_KEY_MOD_NONE = 0x0000,
+
+ /// @brief
+ GAME_KEY_MOD_SHIFT = 0x0001,
+
+ /// @brief
+ GAME_KEY_MOD_CTRL = 0x0002,
+
+ /// @brief
+ GAME_KEY_MOD_ALT = 0x0004,
+
+ /// @brief
+ GAME_KEY_MOD_META = 0x0008,
+
+ /// @brief
+ GAME_KEY_MOD_SUPER = 0x0010,
+
+ /// @brief
+ GAME_KEY_MOD_NUMLOCK = 0x0100,
+
+ /// @brief
+ GAME_KEY_MOD_CAPSLOCK = 0x0200,
+
+ /// @brief
+ GAME_KEY_MOD_SCROLLOCK = 0x0400,
+ } GAME_KEY_MOD;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Type of port on the virtual game console
+ typedef enum GAME_PORT_TYPE
+ {
+ /// @brief Game port unknown
+ GAME_PORT_UNKNOWN,
+
+ /// @brief Game port Keyboard
+ GAME_PORT_KEYBOARD,
+
+ /// @brief Game port mouse
+ GAME_PORT_MOUSE,
+
+ /// @brief Game port controller
+ GAME_PORT_CONTROLLER,
+ } GAME_PORT_TYPE;
+ //----------------------------------------------------------------------------
+
+ /*! @cond PRIVATE */
+ /*!
+ * @brief "C" Game add-on controller layout.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref AddonGameControllerLayout for description of values.
+ */
+ typedef struct game_controller_layout
+ {
+ char* controller_id;
+ bool provides_input; // False for multitaps
+ char** digital_buttons;
+ unsigned int digital_button_count;
+ char** analog_buttons;
+ unsigned int analog_button_count;
+ char** analog_sticks;
+ unsigned int analog_stick_count;
+ char** accelerometers;
+ unsigned int accelerometer_count;
+ char** keys;
+ unsigned int key_count;
+ char** rel_pointers;
+ unsigned int rel_pointer_count;
+ char** abs_pointers;
+ unsigned int abs_pointer_count;
+ char** motors;
+ unsigned int motor_count;
+ } ATTR_PACKED game_controller_layout;
+ /*! @endcond */
+
+ struct game_input_port;
+
+ //============================================================================
+ /// @brief Device that can provide input
+ typedef struct game_input_device
+ {
+ /// @brief ID used in the Kodi controller API
+ const char* controller_id;
+
+ /// @brief
+ const char* port_address;
+
+ /// @brief
+ struct game_input_port* available_ports;
+
+ /// @brief
+ unsigned int port_count;
+ } ATTR_PACKED game_input_device;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Port that can provide input
+ ///
+ /// Ports can accept multiple devices and devices can have multiple ports, so
+ /// the topology of possible configurations is a tree structure of alternating
+ /// port and device nodes.
+ ///
+ typedef struct game_input_port
+ {
+ /// @brief
+ GAME_PORT_TYPE type;
+
+ /// @brief Required for GAME_PORT_CONTROLLER type
+ const char* port_id;
+
+ /// @brief Flag to prevent a port from being disconnected
+ ///
+ /// Set to true to prevent a disconnection option from appearing in the
+ /// GUI.
+ ///
+ bool force_connected;
+
+ /// @brief
+ game_input_device* accepted_devices;
+
+ /// @brief
+ unsigned int device_count;
+ } ATTR_PACKED game_input_port;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief The input topology is the possible ways to connect input devices
+ ///
+ /// This represents the logical topology, which is the possible connections that
+ /// the game client's logic can handle. It is strictly a subset of the physical
+ /// topology. Loops are not allowed.
+ ///
+ typedef struct game_input_topology
+ {
+ /// @brief The list of ports on the virtual game console
+ game_input_port* ports;
+
+ /// @brief The number of ports
+ unsigned int port_count;
+
+ /// @brief A limit on the number of input-providing devices, or -1 for no limit
+ int player_limit;
+ } ATTR_PACKED game_input_topology;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_digital_button_event
+ {
+ /// @brief
+ bool pressed;
+ } ATTR_PACKED game_digital_button_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_analog_button_event
+ {
+ /// @brief
+ float magnitude;
+ } ATTR_PACKED game_analog_button_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_axis_event
+ {
+ /// @brief
+ float position;
+ } ATTR_PACKED game_axis_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_analog_stick_event
+ {
+ /// @brief
+ float x;
+
+ /// @brief
+ float y;
+ } ATTR_PACKED game_analog_stick_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_accelerometer_event
+ {
+ /// @brief
+ float x;
+
+ /// @brief
+ float y;
+
+ /// @brief
+ float z;
+ } ATTR_PACKED game_accelerometer_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_key_event
+ {
+ /// @brief
+ bool pressed;
+
+ /// @brief If the keypress generates a printing character
+ ///
+ /// The unicode value contains the character generated. If the key is a
+ /// non-printing character, e.g. a function or arrow key, the unicode value
+ /// is zero.
+ uint32_t unicode;
+
+ /// @brief
+ GAME_KEY_MOD modifiers;
+ } ATTR_PACKED game_key_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_rel_pointer_event
+ {
+ /// @brief
+ int x;
+
+ /// @brief
+ int y;
+ } ATTR_PACKED game_rel_pointer_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_abs_pointer_event
+ {
+ /// @brief
+ bool pressed;
+
+ /// @brief
+ float x;
+
+ /// @brief
+ float y;
+ } ATTR_PACKED game_abs_pointer_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_motor_event
+ {
+ /// @brief
+ float magnitude;
+ } ATTR_PACKED game_motor_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_input_event
+ {
+ /// @brief
+ GAME_INPUT_EVENT_SOURCE type;
+
+ /// @brief
+ const char* controller_id;
+
+ /// @brief
+ GAME_PORT_TYPE port_type;
+
+ /// @brief
+ const char* port_address;
+
+ /// @brief
+ const char* feature_name;
+ union
+ {
+ /// @brief
+ struct game_digital_button_event digital_button;
+
+ /// @brief
+ struct game_analog_button_event analog_button;
+
+ /// @brief
+ struct game_axis_event axis;
+
+ /// @brief
+ struct game_analog_stick_event analog_stick;
+
+ /// @brief
+ struct game_accelerometer_event accelerometer;
+
+ /// @brief
+ struct game_key_event key;
+
+ /// @brief
+ struct game_rel_pointer_event rel_pointer;
+
+ /// @brief
+ struct game_abs_pointer_event abs_pointer;
+
+ /// @brief
+ struct game_motor_event motor;
+ };
+ } ATTR_PACKED game_input_event;
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+ /// @defgroup cpp_kodi_addon_game_Defs_EnvironmentTypes 8. Environment types
+ /// @ingroup cpp_kodi_addon_game_Defs
+ /// @brief **Environment types**
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Game system timing
+ ///
+ struct game_system_timing
+ {
+ /// @brief FPS of video content.
+ double fps;
+
+ /// @brief Sampling rate of audio.
+ double sample_rate;
+ };
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==--
+
+ /*!
+ * @brief Game properties
+ *
+ * Not to be used outside this header.
+ */
+ typedef struct AddonProps_Game
+ {
+ /*!
+ * The path of the game client being loaded.
+ */
+ const char* game_client_dll_path;
+
+ /*!
+ * Paths to proxy DLLs used to load the game client.
+ */
+ const char** proxy_dll_paths;
+
+ /*!
+ * Number of proxy DLL paths provided.
+ */
+ unsigned int proxy_dll_count;
+
+ /*!
+ * The "system" directories of the frontend. These directories can be used to
+ * store system-specific ROMs such as BIOSes, configuration data, etc.
+ */
+ const char** resource_directories;
+
+ /*!
+ * Number of resource directories provided
+ */
+ unsigned int resource_directory_count;
+
+ /*!
+ * The writable directory of the frontend. This directory can be used to store
+ * SRAM, memory cards, high scores, etc, if the game client cannot use the
+ * regular memory interface, GetMemoryData().
+ */
+ const char* profile_directory;
+
+ /*!
+ * The value of the <supports_vfs> property from addon.xml
+ */
+ bool supports_vfs;
+
+ /*!
+ * The extensions in the <extensions> property from addon.xml
+ */
+ const char** extensions;
+
+ /*!
+ * Number of extensions provided
+ */
+ unsigned int extension_count;
+ } AddonProps_Game;
+
+ typedef void* KODI_GAME_STREAM_HANDLE;
+
+ /*! Structure to transfer the methods from kodi_game_dll.h to Kodi */
+
+ struct AddonInstance_Game;
+
+ /*!
+ * @brief Game callbacks
+ *
+ * Not to be used outside this header.
+ */
+ typedef struct AddonToKodiFuncTable_Game
+ {
+ KODI_HANDLE kodiInstance;
+
+ void (*CloseGame)(KODI_HANDLE kodiInstance);
+ KODI_GAME_STREAM_HANDLE (*OpenStream)(KODI_HANDLE, const struct game_stream_properties*);
+ bool (*GetStreamBuffer)(KODI_HANDLE,
+ KODI_GAME_STREAM_HANDLE,
+ unsigned int,
+ unsigned int,
+ struct game_stream_buffer*);
+ void (*AddStreamData)(KODI_HANDLE, KODI_GAME_STREAM_HANDLE, const struct game_stream_packet*);
+ void (*ReleaseStreamBuffer)(KODI_HANDLE, KODI_GAME_STREAM_HANDLE, struct game_stream_buffer*);
+ void (*CloseStream)(KODI_HANDLE, KODI_GAME_STREAM_HANDLE);
+ game_proc_address_t (*HwGetProcAddress)(KODI_HANDLE kodiInstance, const char* symbol);
+ bool (*InputEvent)(KODI_HANDLE kodiInstance, const struct game_input_event* event);
+ } AddonToKodiFuncTable_Game;
+
+ /*!
+ * @brief Game function hooks
+ *
+ * Not to be used outside this header.
+ */
+ typedef struct KodiToAddonFuncTable_Game
+ {
+ KODI_HANDLE addonInstance;
+
+ GAME_ERROR(__cdecl* LoadGame)(const struct AddonInstance_Game*, const char*);
+ GAME_ERROR(__cdecl* LoadGameSpecial)
+ (const struct AddonInstance_Game*, enum SPECIAL_GAME_TYPE, const char**, size_t);
+ GAME_ERROR(__cdecl* LoadStandalone)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* UnloadGame)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* GetGameTiming)
+ (const struct AddonInstance_Game*, struct game_system_timing*);
+ GAME_REGION(__cdecl* GetRegion)(const struct AddonInstance_Game*);
+ bool(__cdecl* RequiresGameLoop)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* RunFrame)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* Reset)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* HwContextReset)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* HwContextDestroy)(const struct AddonInstance_Game*);
+ bool(__cdecl* HasFeature)(const struct AddonInstance_Game*, const char*, const char*);
+ game_input_topology*(__cdecl* GetTopology)(const struct AddonInstance_Game*);
+ void(__cdecl* FreeTopology)(const struct AddonInstance_Game*, struct game_input_topology*);
+ void(__cdecl* SetControllerLayouts)(const struct AddonInstance_Game*,
+ const struct game_controller_layout*,
+ unsigned int);
+ bool(__cdecl* EnableKeyboard)(const struct AddonInstance_Game*, bool, const char*);
+ bool(__cdecl* EnableMouse)(const struct AddonInstance_Game*, bool, const char*);
+ bool(__cdecl* ConnectController)(const struct AddonInstance_Game*,
+ bool,
+ const char*,
+ const char*);
+ bool(__cdecl* InputEvent)(const struct AddonInstance_Game*, const struct game_input_event*);
+ size_t(__cdecl* SerializeSize)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* Serialize)(const struct AddonInstance_Game*, uint8_t*, size_t);
+ GAME_ERROR(__cdecl* Deserialize)(const struct AddonInstance_Game*, const uint8_t*, size_t);
+ GAME_ERROR(__cdecl* CheatReset)(const struct AddonInstance_Game*);
+ GAME_ERROR(__cdecl* GetMemory)
+ (const struct AddonInstance_Game*, enum GAME_MEMORY, uint8_t**, size_t*);
+ GAME_ERROR(__cdecl* SetCheat)
+ (const struct AddonInstance_Game*, unsigned int, bool, const char*);
+ GAME_ERROR(__cdecl* RCGenerateHashFromFile)
+ (const AddonInstance_Game*, char**, unsigned int, const char*);
+ GAME_ERROR(__cdecl* RCGetGameIDUrl)(const AddonInstance_Game*, char**, const char*);
+ GAME_ERROR(__cdecl* RCGetPatchFileUrl)
+ (const AddonInstance_Game*, char**, const char*, const char*, unsigned int);
+ GAME_ERROR(__cdecl* RCPostRichPresenceUrl)
+ (const AddonInstance_Game*,
+ char**,
+ char**,
+ const char*,
+ const char*,
+ unsigned int,
+ const char*);
+ GAME_ERROR(__cdecl* RCEnableRichPresence)(const AddonInstance_Game*, const char*);
+ GAME_ERROR(__cdecl* RCGetRichPresenceEvaluation)
+ (const AddonInstance_Game*, char**, unsigned int);
+ GAME_ERROR(__cdecl* RCResetRuntime)(const AddonInstance_Game*);
+ void(__cdecl* FreeString)(const AddonInstance_Game*, char*);
+ } KodiToAddonFuncTable_Game;
+
+ /*!
+ * @brief Game instance
+ *
+ * Not to be used outside this header.
+ */
+ typedef struct AddonInstance_Game
+ {
+ struct AddonProps_Game* props;
+ struct AddonToKodiFuncTable_Game* toKodi;
+ struct KodiToAddonFuncTable_Game* toAddon;
+ } AddonInstance_Game;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_GAME_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/imagedecoder.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/imagedecoder.h
new file mode 100644
index 0000000..a72e2f8
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/imagedecoder.h
@@ -0,0 +1,450 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_IMAGEDECODER_H
+#define C_API_ADDONINSTANCE_IMAGEDECODER_H
+
+#include "../addon_base.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef KODI_ADDON_INSTANCE_HDL KODI_ADDON_IMAGEDECODER_HDL;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_FMT enum ADDON_IMG_FMT
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Image format types**\n
+ /// Used to define wanted target format where image decoder should give to
+ /// Kodi.
+ ///
+ ///@{
+ typedef enum ADDON_IMG_FMT
+ {
+ /// @brief A 32-bit ARGB pixel format, with alpha, that uses 8 bits per
+ /// channel, ARGBARGB...
+ ADDON_IMG_FMT_A8R8G8B8 = 1,
+
+ /// @brief A 8, alpha only, 8bpp, AAA...
+ ADDON_IMG_FMT_A8 = 2,
+
+ /// @brief RGBA 8:8:8:8, with alpha, 32bpp, RGBARGBA...
+ ADDON_IMG_FMT_RGBA8 = 3,
+
+ /// @brief RGB 8:8:8, with alpha, 24bpp, RGBRGB...
+ ADDON_IMG_FMT_RGB8 = 4
+ } ADDON_IMG_FMT;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_ORIENTATION enum ADDON_IMG_ORIENTATION
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Image orientation types**\n
+ /// Used to define how image becomes orientated for show.
+ ///
+ ///@{
+ typedef enum ADDON_IMG_ORIENTATION
+ {
+ /// @brief If not available
+ ADDON_IMG_ORIENTATION_NONE = 0,
+
+ /// @brief Flip horizontal
+ ADDON_IMG_ORIENTATION_FLIP_HORIZONTAL = 1,
+
+ /// @brief Rotate 180° CCW
+ ADDON_IMG_ORIENTATION_ROTATE_180_CCW = 2,
+
+ /// @brief Flip vertical
+ ADDON_IMG_ORIENTATION_FLIP_VERTICAL = 3,
+
+ /// @brief Transpose
+ ADDON_IMG_ORIENTATION_TRANSPOSE = 4,
+
+ /// @brief Rotate 270° CCW
+ ADDON_IMG_ORIENTATION_ROTATE_270_CCW = 5,
+
+ /// @brief Transpose off axis
+ ADDON_IMG_ORIENTATION_TRANSPOSE_OFF_AXIS = 6,
+
+ /// @brief Rotate 90° CCW
+ ADDON_IMG_ORIENTATION_ROTATE_90_CCW = 7,
+ } ADDON_IMG_ORIENTATION;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_COLOR enum ADDON_IMG_COLOR
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Image color type**\n
+ /// To set image as colored or black/white.
+ ///
+ ///@{
+ typedef enum ADDON_IMG_COLOR
+ {
+ /// @brief Colored image
+ ADDON_IMG_COLOR_COLORED,
+
+ /// @brief Black/White image
+ ADDON_IMG_COLOR_BLACK_WHITE
+ } ADDON_IMG_COLOR;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_METERING_MODE enum ADDON_IMG_METERING_MODE
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Image metering mode**
+ ///
+ ///@{
+ typedef enum ADDON_IMG_METERING_MODE
+ {
+ /// @brief 0 = Unknown
+ ADDON_IMG_METERING_MODE_UNKNOWN = 0,
+
+ /// @brief 1 = Average
+ ADDON_IMG_METERING_MODE_AVERAGE = 1,
+
+ /// @brief 2 = Center-weighted average
+ ADDON_IMG_METERING_MODE_CENTER_WEIGHT = 2,
+
+ /// @brief 3 = Spot
+ ADDON_IMG_METERING_MODE_SPOT = 3,
+
+ /// @brief 4 = MultiSpot
+ ADDON_IMG_METERING_MODE_MULTI_SPOT = 4,
+
+ /// @brief 5 = Pattern
+ ADDON_IMG_METERING_MODE_MULTI_SEGMENT = 5,
+
+ /// @brief 6 = Partial
+ ADDON_IMG_METERING_MODE_PARTIAL = 6,
+
+ /// @brief 255 = other
+ ADDON_IMG_METERING_MODE_OTHER = 255,
+ } ADDON_IMG_METERING_MODE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_EXPOSURE_PROGRAM enum ADDON_IMG_EXPOSURE_PROGRAM
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Exposure program**\n
+ /// The class of the program used by the camera to set exposure when the picture is taken.
+ ///
+ ///@{
+ typedef enum ADDON_IMG_EXPOSURE_PROGRAM
+ {
+ /// @brief 0 = Not Defined
+ ADDON_IMG_EXPOSURE_PROGRAM_UNDEFINED = 0,
+
+ /// @brief 1 = Manual
+ ADDON_IMG_EXPOSURE_PROGRAM_MANUAL = 1,
+
+ /// @brief 2 = Normal program
+ ADDON_IMG_EXPOSURE_PROGRAM_NORMAL = 2,
+
+ /// @brief 3 = Aperture-priority
+ ADDON_IMG_EXPOSURE_PROGRAM_APERTURE_PRIORITY = 3,
+
+ /// @brief 4 = Shutter speed priority
+ ADDON_IMG_EXPOSURE_PROGRAM_SHUTTER_SPEED_PRIORITY = 4,
+
+ /// @brief 5 = Creative program (biased toward depth of field)
+ ADDON_IMG_EXPOSURE_PROGRAM_CREATIVE = 5,
+
+ /// @brief 6 = Action program (biased toward fast shutter speed)
+ ADDON_IMG_EXPOSURE_PROGRAM_ACTION = 6,
+
+ /// @brief 7 = Portrait mode (for closeup photos with the background out of focus)
+ ADDON_IMG_EXPOSURE_PROGRAM_PORTRAIT = 7,
+
+ /// @brief 8 = Landscape mode (for landscape photos with the background in focus)
+ ADDON_IMG_EXPOSURE_PROGRAM_LANDSCAPE = 8,
+
+ /// @brief 9 = Bulb
+ /// @note The value of 9 is not standard EXIF, but is used by the Canon EOS 7D
+ ADDON_IMG_EXPOSURE_PROGRAM_BULB = 9
+ } ADDON_IMG_EXPOSURE_PROGRAM;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_EXPOSURE_MODE enum ADDON_IMG_EXPOSURE_MODE
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Exposure mode**\n
+ /// Indicates the exposure mode set when the image was shot.
+ ///
+ /// In auto-bracketing mode, the camera shoots a series of frames of the same
+ /// scene at different exposure settings.
+ ///
+ ///@{
+ typedef enum ADDON_IMG_EXPOSURE_MODE
+ {
+ /// @brief 0 = Auto exposure
+ ADDON_IMG_EXPOSURE_MODE_AUTO = 0,
+
+ /// @brief 1 = Manual exposure
+ ADDON_IMG_EXPOSURE_MODE_MANUAL = 1,
+
+ /// @brief 2 = Auto bracket
+ ADDON_IMG_EXPOSURE_MODE_AUTO_TRACKED = 2,
+ } ADDON_IMG_EXPOSURE_MODE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_LIGHT_SOURCE enum ADDON_IMG_LIGHT_SOURCE
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Kind of light source**
+ ///
+ ///@{
+ typedef enum ADDON_IMG_LIGHT_SOURCE
+ {
+ /// @brief 0 = Unknown
+ ADDON_IMG_LIGHT_SOURCE_UNKNOWN = 0,
+
+ /// @brief 1 = Daylight
+ ADDON_IMG_LIGHT_SOURCE_DAYLIGHT = 1,
+
+ /// @brief 2 = Fluorescent
+ ADDON_IMG_LIGHT_SOURCE_FLUORESCENT = 2,
+
+ /// @brief 3 = Tungsten (incandescent light)
+ ADDON_IMG_LIGHT_SOURCE_TUNGSTEN = 3,
+
+ /// @brief 4 = Flash
+ ADDON_IMG_LIGHT_SOURCE_FLASH = 4,
+
+ /// @brief 9 = Fine weather
+ ADDON_IMG_LIGHT_SOURCE_FINE_WEATHER = 9,
+
+ /// @brief 10 = Cloudy weather
+ ADDON_IMG_LIGHT_SOURCE_CLOUDY_WEATHER = 10,
+
+ /// @brief 11 = Shade
+ ADDON_IMG_LIGHT_SOURCE_SHADE = 11,
+
+ /// @brief 12 = Daylight fluorescent (D 5700 - 7100K)
+ ADDON_IMG_LIGHT_SOURCE_DAYLIGHT_FLUORESCENT = 12,
+
+ /// @brief 13 = Day white fluorescent (N 4600 - 5400K)
+ ADDON_IMG_LIGHT_SOURCE_DAY_WHITE_FLUORESCENT = 13,
+
+ /// @brief 14 = Cool white fluorescent (W 3900 - 4500K)
+ ADDON_IMG_LIGHT_SOURCE_COOL_WHITE_FLUORESCENT = 14,
+
+ /// @brief 15 = White fluorescent (WW 3200 - 3700K)
+ ADDON_IMG_LIGHT_SOURCE_WHITE_FLUORESCENT = 15,
+
+ /// @brief 17 = Standard light A
+ ADDON_IMG_LIGHT_SOURCE_STANDARD_LIGHT_A = 17,
+
+ /// @brief 18 = Standard light B
+ ADDON_IMG_LIGHT_SOURCE_STANDARD_LIGHT_B = 18,
+
+ /// @brief 19 = Standard light C
+ ADDON_IMG_LIGHT_SOURCE_STANDARD_LIGHT_C = 19,
+
+ /// @brief 20 = D55
+ ADDON_IMG_LIGHT_SOURCE_D55 = 20,
+
+ /// @brief 21 = D65
+ ADDON_IMG_LIGHT_SOURCE_D65 = 21,
+
+ /// @brief 22 = D75
+ ADDON_IMG_LIGHT_SOURCE_D75 = 22,
+
+ /// @brief 23 = D50
+ ADDON_IMG_LIGHT_SOURCE_D50 = 23,
+
+ /// @brief 24 = ISO Studio Tungsten
+ ADDON_IMG_LIGHT_SOURCE_ISO_STUDIO_TUNGSTEN = 24,
+
+ /// @brief 255 = Other
+ ADDON_IMG_LIGHT_SOURCE_OTHER = 255,
+ } ADDON_IMG_LIGHT_SOURCE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_imagedecoder_Defs_ADDON_IMG_FLASH_TYPE enum ADDON_IMG_FLASH_TYPE
+ /// @ingroup cpp_kodi_addon_imagedecoder_Defs
+ /// @brief **Flash Values**
+ ///
+ ///@{
+ typedef enum ADDON_IMG_FLASH_TYPE
+ {
+ /// @brief 0x0 = No Flash
+ ADDON_IMG_FLASH_TYPE_NO_FLASH = 0x0,
+
+ /// @brief 0x1 = Fired
+ ADDON_IMG_FLASH_TYPE_FIRED = 0x1,
+
+ /// @brief 0x5 = Fired, Return not detected
+ ADDON_IMG_FLASH_TYPE_FIRED_RETURN_NOT_DETECTED = 0x5,
+
+ /// @brief 0x7 = Fired, Return detected
+ ADDON_IMG_FLASH_TYPE_FIRED_RETURN_DETECTED = 0x7,
+
+ /// @brief 0x8 = On, Did not fire
+ ADDON_IMG_FLASH_TYPE_ = 0x8,
+
+ /// @brief 0x9 = On, Fired
+ ADDON_IMG_FLASH_TYPE_ON_Fired = 0x9,
+
+ /// @brief 0xd = On, Return not detected
+ ADDON_IMG_FLASH_TYPE_ON_RETURN_NOT_DETECTED = 0xd,
+
+ /// @brief 0xf = On, Return detected
+ ADDON_IMG_FLASH_TYPE_ON_RETURN_DETECTED = 0xf,
+
+ /// @brief 0x10 = Off, Did not fire
+ ADDON_IMG_FLASH_TYPE_OFF_DID_NOT_FIRE = 0x10,
+
+ /// @brief 0x14 = Off, Did not fire, Return not detected
+ ADDON_IMG_FLASH_TYPE_OFF_DID_NOT_FIRE_RETURN_NOT_DETECTED = 0x14,
+
+ /// @brief 0x18 = Auto, Did not fire
+ ADDON_IMG_FLASH_TYPE_AUTO_DID_NOT_FIRE = 0x18,
+
+ /// @brief 0x19 = Auto, Fired
+ ADDON_IMG_FLASH_TYPE_AUTO_FIRED = 0x19,
+
+ /// @brief 0x1d = Auto, Fired, Return not detected
+ ADDON_IMG_FLASH_TYPE_AUTO_FIRED_RETURN_NOT_DETECTED = 0x1d,
+
+ /// @brief 0x1f = Auto, Fired, Return detected
+ ADDON_IMG_FLASH_TYPE_AUTO_FIRED_RETURN_DETECTED = 0x1f,
+
+ /// @brief 0x20 = No flash function
+ ADDON_IMG_FLASH_TYPE_NO_FLASH_FUNCTION = 0x20,
+
+ /// @brief 0x30 = Off, No flash function
+ ADDON_IMG_FLASH_TYPE_OFF_NO_FLASH_FUNCTION = 0x30,
+
+ /// @brief 0x41 = Fired, Red-eye reduction
+ ADDON_IMG_FLASH_TYPE_FIRED_REDEYE_REDUCTION = 0x41,
+
+ /// @brief 0x45 = Fired, Red-eye reduction, Return not detected
+ ADDON_IMG_FLASH_TYPE_FIRED_REDEYE_REDUCTION_RETURN_NOT_DETECTED = 0x45,
+
+ /// @brief 0x47 = Fired, Red-eye reduction, Return detected
+ ADDON_IMG_FLASH_TYPE_FIRED_REDEYE_REDUCTION_RETURN_DETECTED = 0x47,
+
+ /// @brief 0x49 = On, Red-eye reduction
+ ADDON_IMG_FLASH_TYPE_ON_REDEYE_REDUCTION = 0x49,
+
+ /// @brief 0x4d = On, Red-eye reduction, Return not detected
+ ADDON_IMG_FLASH_TYPE_ON_REDEYE_REDUCTION_RETURN_NOT_DETECTED = 0x4d,
+
+ /// @brief 0x4f = On, Red-eye reduction, Return detected
+ ADDON_IMG_FLASH_TYPE_ON_REDEYE_REDUCTION_RETURN_DETECTED = 0x4f,
+
+ /// @brief 0x50 = Off, Red-eye reduction
+ ADDON_IMG_FLASH_TYPE_OFF_REDEYE_REDUCTION = 0x50,
+
+ /// @brief 0x58 = Auto, Did not fire, Red-eye reduction
+ ADDON_IMG_FLASH_TYPE_AUTO_DID_NOT_FIRE_REDEYE_REDUCTION = 0x58,
+
+ /// @brief 0x59 = Auto, Fired, Red-eye reduction
+ ADDON_IMG_FLASH_TYPE_AUTO_FIRED_REDEYE_REDUCTION = 0x59,
+
+ /// @brief 0x5d = Auto, Fired, Red-eye reduction, Return not detected
+ ADDON_IMG_FLASH_TYPE_AUTO_FIRED_REDEYE_REDUCTION_RETURN_NOT_DETECTED = 0x5d,
+
+ /// @brief 0x5f = Auto, Fired, Red-eye reduction, Return detected
+ ADDON_IMG_FLASH_TYPE_AUTO_FIRED_REDEYE_REDUCTION_RETURN_DETECTED = 0x5f,
+ } ADDON_IMG_FLASH_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ struct KODI_ADDON_IMAGEDECODER_INFO_TAG
+ {
+ int width;
+ int height;
+ float distance;
+ enum ADDON_IMG_ORIENTATION orientation;
+ enum ADDON_IMG_COLOR color;
+ enum ADDON_IMG_METERING_MODE metering_mode;
+ float exposure_time;
+ float exposure_bias;
+ enum ADDON_IMG_EXPOSURE_PROGRAM exposure_program;
+ enum ADDON_IMG_EXPOSURE_MODE exposure_mode;
+ time_t time_created;
+ float aperture_f_number;
+ enum ADDON_IMG_FLASH_TYPE flash_used;
+ int focal_length;
+ int focal_length_in_35mm_format;
+ float digital_zoom_ratio;
+ float iso_speed;
+ enum ADDON_IMG_LIGHT_SOURCE light_source;
+
+ bool gps_info_present;
+ char latitude_ref;
+ float latitude[3]; /* Deg,min,sec */
+ char longitude_ref;
+ float longitude[3]; /* Deg,min,sec */
+ int altitude_ref;
+ float altitude;
+
+ char* camera_manufacturer;
+ char* camera_model;
+ char* author;
+ char* description;
+ char* copyright;
+ };
+
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_IMAGEDECODER_SUPPORTS_FILE_V1)(
+ const KODI_ADDON_IMAGEDECODER_HDL hdl, const char* file);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_IMAGEDECODER_READ_TAG_V1)(
+ const KODI_ADDON_IMAGEDECODER_HDL hdl,
+ const char* file,
+ struct KODI_ADDON_IMAGEDECODER_INFO_TAG* info);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_IMAGEDECODER_LOAD_IMAGE_FROM_MEMORY_V1)(
+ const KODI_ADDON_IMAGEDECODER_HDL hdl,
+ const char* mimetype,
+ const uint8_t* buffer,
+ size_t buf_size,
+ unsigned int* width,
+ unsigned int* height);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_IMAGEDECODER_DECODE_V1)(
+ const KODI_ADDON_IMAGEDECODER_HDL hdl,
+ uint8_t* pixels,
+ size_t pixels_size,
+ unsigned int width,
+ unsigned int height,
+ unsigned int pitch,
+ enum ADDON_IMG_FMT format);
+
+ typedef struct KodiToAddonFuncTable_ImageDecoder
+ {
+ PFN_KODI_ADDON_IMAGEDECODER_SUPPORTS_FILE_V1 supports_file;
+ PFN_KODI_ADDON_IMAGEDECODER_READ_TAG_V1 read_tag;
+ PFN_KODI_ADDON_IMAGEDECODER_LOAD_IMAGE_FROM_MEMORY_V1 load_image_from_memory;
+ PFN_KODI_ADDON_IMAGEDECODER_DECODE_V1 decode;
+ } KodiToAddonFuncTable_ImageDecoder;
+
+ typedef struct AddonToKodiFuncTable_ImageDecoder
+ {
+ KODI_HANDLE kodi_instance;
+ } AddonToKodiFuncTable_ImageDecoder;
+
+ typedef struct AddonInstance_ImageDecoder
+ {
+ struct AddonToKodiFuncTable_ImageDecoder* toKodi;
+ struct KodiToAddonFuncTable_ImageDecoder* toAddon;
+ } AddonInstance_ImageDecoder;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_IMAGEDECODER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h
new file mode 100644
index 0000000..7e33015
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h
@@ -0,0 +1,708 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_INPUTSTREAM_H
+#define C_API_ADDONINSTANCE_INPUTSTREAM_H
+
+#include "../addon_base.h"
+#include "inputstream/demux_packet.h"
+#include "inputstream/stream_codec.h"
+#include "inputstream/stream_constants.h"
+#include "inputstream/stream_crypto.h"
+#include "inputstream/timing_constants.h"
+
+#include <time.h>
+
+// Increment this level always if you add features which can lead to compile failures in the addon
+#define INPUTSTREAM_VERSION_LEVEL 4
+
+#define INPUTSTREAM_MAX_INFO_COUNT 8
+#define INPUTSTREAM_MAX_STREAM_COUNT 256
+#define INPUTSTREAM_MAX_STRING_NAME_SIZE 256
+#define INPUTSTREAM_MAX_STRING_CODEC_SIZE 32
+#define INPUTSTREAM_MAX_STRING_LANGUAGE_SIZE 64
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //==============================================================================
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface_InputstreamCapabilities
+ /// @brief **Capability types of inputstream addon.**\n
+ /// This values are needed to tell Kodi which options are supported on the addon.
+ ///
+ /// If one of this is defined, then the corresponding methods from
+ /// @ref cpp_kodi_addon_inputstream "kodi::addon::CInstanceInputStream" need
+ /// to be implemented.
+ ///
+ /// Used on @ref kodi::addon::CInstanceInputStream::GetCapabilities().
+ ///
+ ///@{
+ enum INPUTSTREAM_MASKTYPE
+ {
+ /// @brief **0000 0000 0000 0001 :** Supports interface demuxing.
+ ///
+ /// If set must be @ref cpp_kodi_addon_inputstream_Demux "Demux support" included.
+ INPUTSTREAM_SUPPORTS_IDEMUX = (1 << 0),
+
+ /// @brief **0000 0000 0000 0010 :** Supports interface position time.
+ ///
+ /// This means that the start time and the current stream time are used.
+ ///
+ /// If set must be @ref cpp_kodi_addon_inputstream_Time "Time support" included.
+ INPUTSTREAM_SUPPORTS_IPOSTIME = (1 << 1),
+
+ /// @brief **0000 0000 0000 0100 :** Supports interface for display time.
+ ///
+ /// This will call up the complete stream time information. The start time
+ /// and the individual PTS times are then given using @ref cpp_kodi_addon_inputstream_Defs_Times.
+ ///
+ /// If set must be @ref cpp_kodi_addon_inputstream_Times "Times support" included.
+ INPUTSTREAM_SUPPORTS_IDISPLAYTIME = (1 << 2),
+
+ /// @brief **0000 0000 0000 1000 :** Supports seek
+ INPUTSTREAM_SUPPORTS_SEEK = (1 << 3),
+
+ /// @brief **0000 0000 0001 0000 :** Supports pause
+ INPUTSTREAM_SUPPORTS_PAUSE = (1 << 4),
+
+ /// @brief **0000 0000 0010 0000 :** Supports interface to give position time.
+ ///
+ /// This will only ask for the current time of the stream, not for length or
+ /// start.
+ ///
+ /// If set must be @ref cpp_kodi_addon_inputstream_PosTime "Position time support" included.
+ INPUTSTREAM_SUPPORTS_ITIME = (1 << 5),
+
+ /// @brief **0000 0000 0100 0000 :** Supports interface for chapter selection.
+ ///
+ /// If set must be @ref cpp_kodi_addon_inputstream_Chapter "Chapter support" included.
+ INPUTSTREAM_SUPPORTS_ICHAPTER = (1 << 6),
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief InputStream add-on capabilities. All capabilities are set to "false" as default.
+ */
+ struct INPUTSTREAM_CAPABILITIES
+ {
+ /// set of supported capabilities
+ uint32_t m_mask;
+ };
+
+ /*!
+ * @brief structure of key/value pairs passed to addon on Open()
+ */
+ struct INPUTSTREAM_PROPERTY
+ {
+ const char* m_strURL;
+ const char* m_mimeType;
+
+ unsigned int m_nCountInfoValues;
+ struct LISTITEMPROPERTY
+ {
+ const char* m_strKey;
+ const char* m_strValue;
+ } m_ListItemProperties[STREAM_MAX_PROPERTY_COUNT];
+
+ const char* m_libFolder;
+ const char* m_profileFolder;
+ };
+
+ /*!
+ * @brief Array of stream IDs
+ */
+ struct INPUTSTREAM_IDS
+ {
+ unsigned int m_streamCount;
+ unsigned int m_streamIds[INPUTSTREAM_MAX_STREAM_COUNT];
+ };
+
+ /*!
+ * @brief MASTERING Metadata
+ */
+ struct INPUTSTREAM_MASTERING_METADATA
+ {
+ double primary_r_chromaticity_x;
+ double primary_r_chromaticity_y;
+ double primary_g_chromaticity_x;
+ double primary_g_chromaticity_y;
+ double primary_b_chromaticity_x;
+ double primary_b_chromaticity_y;
+ double white_point_chromaticity_x;
+ double white_point_chromaticity_y;
+ double luminance_max;
+ double luminance_min;
+ };
+
+ /*!
+ * @brief CONTENTLIGHT Metadata
+ */
+ struct INPUTSTREAM_CONTENTLIGHT_METADATA
+ {
+ uint64_t max_cll;
+ uint64_t max_fall;
+ };
+
+ //==============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_INPUTSTREAM_TYPE enum INPUTSTREAM_TYPE
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Inputstream types**\n
+ /// To identify type on stream.
+ ///
+ /// Used on @ref kodi::addon::InputstreamInfo::SetStreamType and @ref kodi::addon::InputstreamInfo::GetStreamType.
+ ///
+ ///@{
+ enum INPUTSTREAM_TYPE
+ {
+ /// @brief **0 :** To set nothing defined
+ INPUTSTREAM_TYPE_NONE = 0,
+
+ /// @brief **1 :** To identify @ref cpp_kodi_addon_inputstream_Defs_Info as Video
+ INPUTSTREAM_TYPE_VIDEO,
+
+ /// @brief **2 :** To identify @ref cpp_kodi_addon_inputstream_Defs_Info as Audio
+ INPUTSTREAM_TYPE_AUDIO,
+
+ /// @brief **3 :** To identify @ref cpp_kodi_addon_inputstream_Defs_Info as Subtitle
+ INPUTSTREAM_TYPE_SUBTITLE,
+
+ /// @brief **4 :** To identify @ref cpp_kodi_addon_inputstream_Defs_Info as Teletext
+ INPUTSTREAM_TYPE_TELETEXT,
+
+ /// @brief **5 :** To identify @ref cpp_kodi_addon_inputstream_Defs_Info as Radio RDS
+ INPUTSTREAM_TYPE_RDS,
+
+ /// @brief **6 :** To identify @ref cpp_kodi_addon_inputstream_Defs_Info as Audio ID3 tags
+ INPUTSTREAM_TYPE_ID3,
+ };
+ ///@}
+ //------------------------------------------------------------------------------
+
+ //==============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_INPUTSTREAM_CODEC_FEATURES enum INPUTSTREAM_CODEC_FEATURES
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Inputstream codec features**\n
+ /// To identify special extra features used for optional codec on inputstream.
+ ///
+ /// Used on @ref kodi::addon::InputstreamInfo::SetFeatures and @ref kodi::addon::InputstreamInfo::GetFeatures.
+ ///
+ /// @note These variables are bit flags which are created using "|" can be used together.
+ ///
+ ///@{
+ enum INPUTSTREAM_CODEC_FEATURES
+ {
+ /// @brief **0000 0000 0000 0000 :** Empty to set if nothing is used
+ INPUTSTREAM_FEATURE_NONE = 0,
+
+ /// @brief **0000 0000 0000 0001 :** To set addon decode should used with @ref cpp_kodi_addon_videocodec.
+ INPUTSTREAM_FEATURE_DECODE = (1 << 0)
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_INPUTSTREAM_FLAGS enum INPUTSTREAM_FLAGS
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Inputstream flags**\n
+ /// To identify extra stream flags used on inputstream.
+ ///
+ /// Used on @ref kodi::addon::InputstreamInfo::SetFlags and @ref kodi::addon::InputstreamInfo::GetFlags.
+ ///
+ /// @note These variables are bit flags which are created using "|" can be used together.
+ ///
+ ///@{
+ enum INPUTSTREAM_FLAGS
+ {
+ /// @brief **0000 0000 0000 0000 :** Empty to set if nothing is used
+ INPUTSTREAM_FLAG_NONE = 0,
+
+ /// @brief **0000 0000 0000 0001 :** Default
+ INPUTSTREAM_FLAG_DEFAULT = (1 << 0),
+
+ /// @brief **0000 0000 0000 0010 :** Dub
+ INPUTSTREAM_FLAG_DUB = (1 << 1),
+
+ /// @brief **0000 0000 0000 0100 :** Original
+ INPUTSTREAM_FLAG_ORIGINAL = (1 << 2),
+
+ /// @brief **0000 0000 0000 1000 :** Comment
+ INPUTSTREAM_FLAG_COMMENT = (1 << 3),
+
+ /// @brief **0000 0000 0001 0000 :** Lyrics
+ INPUTSTREAM_FLAG_LYRICS = (1 << 4),
+
+ /// @brief **0000 0000 0010 0000 :** Karaoke
+ INPUTSTREAM_FLAG_KARAOKE = (1 << 5),
+
+ /// @brief **0000 0000 0100 0000 :** Forced
+ INPUTSTREAM_FLAG_FORCED = (1 << 6),
+
+ /// @brief **0000 0000 1000 0000 :** Hearing impaired
+ INPUTSTREAM_FLAG_HEARING_IMPAIRED = (1 << 7),
+
+ /// @brief **0000 0001 0000 0000 :** Visual impaired
+ INPUTSTREAM_FLAG_VISUAL_IMPAIRED = (1 << 8),
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ // Keep in sync with AVColorSpace
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_INPUTSTREAM_COLORSPACE enum INPUTSTREAM_COLORSPACE
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Inputstream color space flags**\n
+ /// YUV colorspace type. These values match the ones defined by ISO/IEC 23001-8_2013 § 7.3.
+ ///
+ /// Used on @ref kodi::addon::InputstreamInfo::SetColorSpace and @ref kodi::addon::InputstreamInfo::GetColorSpace.
+ ///
+ ///@{
+ enum INPUTSTREAM_COLORSPACE
+ {
+ /// @brief **0 :** Order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
+ INPUTSTREAM_COLORSPACE_RGB = 0,
+
+ /// @brief **1 :** Also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+ INPUTSTREAM_COLORSPACE_BT709 = 1,
+
+ /// @brief **2 :** To set stream is unspecified
+ INPUTSTREAM_COLORSPACE_UNSPECIFIED = 2,
+
+ /// @brief **2 :** To set stream is unknown
+ /// @note Same as @ref INPUTSTREAM_COLORSPACE_UNSPECIFIED
+ INPUTSTREAM_COLORSPACE_UNKNOWN = INPUTSTREAM_COLORSPACE_UNSPECIFIED, // compatibility
+
+ /// @brief **3 :** To set colorspace reserved
+ INPUTSTREAM_COLORSPACE_RESERVED = 3,
+
+ /// @brief **4 :** FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
+ INPUTSTREAM_COLORSPACE_FCC = 4,
+
+ /// @brief **5 :** Also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+ INPUTSTREAM_COLORSPACE_BT470BG = 5,
+
+ /// @brief **6 :** Also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
+ INPUTSTREAM_COLORSPACE_SMPTE170M = 6,
+
+ /// @brief **7 :** Functionally identical to above @ref INPUTSTREAM_COLORSPACE_SMPTE170M
+ INPUTSTREAM_COLORSPACE_SMPTE240M = 7,
+
+ /// @brief **8 :** Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+ INPUTSTREAM_COLORSPACE_YCGCO = 8,
+
+ /// @brief **8 :** To set colorspace as YCOCG
+ /// @note Same as @ref INPUTSTREAM_COLORSPACE_YCGCO
+ INPUTSTREAM_COLORSPACE_YCOCG = INPUTSTREAM_COLORSPACE_YCGCO,
+
+ /// @brief **9 :** ITU-R BT2020 non-constant luminance system
+ INPUTSTREAM_COLORSPACE_BT2020_NCL = 9,
+
+ /// @brief **10 :** ITU-R BT2020 constant luminance system
+ INPUTSTREAM_COLORSPACE_BT2020_CL = 10,
+
+ /// @brief **11 :** SMPTE 2085, Y'D'zD'x
+ INPUTSTREAM_COLORSPACE_SMPTE2085 = 11,
+
+ /// @brief **12 :** Chromaticity-derived non-constant luminance system
+ INPUTSTREAM_COLORSPACE_CHROMA_DERIVED_NCL = 12,
+
+ /// @brief **13 :** Chromaticity-derived constant luminance system
+ INPUTSTREAM_COLORSPACE_CHROMA_DERIVED_CL = 13,
+
+ /// @brief **14 :** ITU-R BT.2100-0, ICtCp
+ INPUTSTREAM_COLORSPACE_ICTCP = 14,
+
+ /// @brief The maximum value to use in a list.
+ INPUTSTREAM_COLORSPACE_MAX
+ };
+ ///@}
+ //------------------------------------------------------------------------------
+
+ // Keep in sync with AVColorPrimaries
+ //==============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_INPUTSTREAM_COLORPRIMARIES enum INPUTSTREAM_COLORPRIMARIES
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Inputstream color primaries flags**\n
+ /// Chromaticity coordinates of the source primaries. These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1.
+ ///
+ /// Used on @ref kodi::addon::InputstreamInfo::SetColorPrimaries and @ref kodi::addon::InputstreamInfo::GetColorPrimaries.
+ ///
+ ///@{
+ enum INPUTSTREAM_COLORPRIMARIES
+ {
+ /// @brief **0 :** Reserved
+ INPUTSTREAM_COLORPRIMARY_RESERVED0 = 0,
+
+ /// @brief **1 :** Also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
+ INPUTSTREAM_COLORPRIMARY_BT709 = 1,
+
+ /// @brief **2 :** Unspecified
+ INPUTSTREAM_COLORPRIMARY_UNSPECIFIED = 2,
+
+ /// @brief **3 :** Reserved
+ INPUTSTREAM_COLORPRIMARY_RESERVED = 3,
+
+ /// @brief **4 :** Also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
+ INPUTSTREAM_COLORPRIMARY_BT470M = 4,
+
+ /// @brief **5 :** Also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
+ INPUTSTREAM_COLORPRIMARY_BT470BG = 5,
+
+ /// @brief **6 :** Also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
+ INPUTSTREAM_COLORPRIMARY_SMPTE170M = 6,
+
+ /// @brief **7 :** Functionally identical to above
+ INPUTSTREAM_COLORPRIMARY_SMPTE240M = 7,
+
+ /// @brief **8 :** Colour filters using Illuminant C
+ INPUTSTREAM_COLORPRIMARY_FILM = 8,
+
+ /// @brief **9 :** ITU-R BT2020
+ INPUTSTREAM_COLORPRIMARY_BT2020 = 9,
+
+ /// @brief **10 :** SMPTE ST 428-1 (CIE 1931 XYZ)
+ INPUTSTREAM_COLORPRIMARY_SMPTE428 = 10,
+
+ /// @brief **10 :**
+ /// @note Same as @ref INPUTSTREAM_COLORPRIMARY_SMPTE428
+ INPUTSTREAM_COLORPRIMARY_SMPTEST428_1 = INPUTSTREAM_COLORPRIMARY_SMPTE428,
+
+ /// @brief **11 :** SMPTE ST 431-2 (2011) / DCI P3
+ INPUTSTREAM_COLORPRIMARY_SMPTE431 = 11,
+
+ /// @brief **12 :** SMPTE ST 432-1 (2010) / P3 D65 / Display P3
+ INPUTSTREAM_COLORPRIMARY_SMPTE432 = 12,
+
+ /// @brief **22 :** JEDEC P22 phosphors
+ INPUTSTREAM_COLORPRIMARY_JEDEC_P22 = 22,
+
+ /// @brief The maximum value to use in a list.
+ INPUTSTREAM_COLORPRIMARY_MAX
+ };
+ ///@}
+ //------------------------------------------------------------------------------
+
+ // Keep in sync with AVColorRange
+ //==============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_INPUTSTREAM_COLORRANGE enum INPUTSTREAM_COLORRANGE
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Inputstream color range flags**\n
+ /// MPEG vs JPEG YUV range.
+ ///
+ /// Used on @ref kodi::addon::InputstreamInfo::SetColorRange and @ref kodi::addon::InputstreamInfo::GetColorRange.
+ ///
+ ///@{
+ enum INPUTSTREAM_COLORRANGE
+ {
+ /// @brief **0 :** To define as unknown
+ INPUTSTREAM_COLORRANGE_UNKNOWN = 0,
+
+ /// @brief **1 :** The normal 219*2^(n-8) "MPEG" YUV ranges
+ INPUTSTREAM_COLORRANGE_LIMITED,
+
+ /// @brief **2 :** The normal 2^n-1 "JPEG" YUV ranges
+ INPUTSTREAM_COLORRANGE_FULLRANGE,
+
+ /// @brief The maximum value to use in a list.
+ INPUTSTREAM_COLORRANGE_MAX
+ };
+ ///@}
+ //------------------------------------------------------------------------------
+
+ // keep in sync with AVColorTransferCharacteristic
+ //==============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_INPUTSTREAM_COLORTRC enum INPUTSTREAM_COLORTRC
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Inputstream color TRC flags**\n
+ /// Color Transfer Characteristic. These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2.
+ ///
+ /// Used on @ref kodi::addon::InputstreamInfo::SetColorTransferCharacteristic and @ref kodi::addon::InputstreamInfo::GetColorTransferCharacteristic.
+ ///
+ ///@{
+ enum INPUTSTREAM_COLORTRC
+ {
+ /// @brief **0 :** Reserved
+ INPUTSTREAM_COLORTRC_RESERVED0 = 0,
+
+ /// @brief **1 :** Also ITU-R BT1361
+ INPUTSTREAM_COLORTRC_BT709 = 1,
+
+ /// @brief **2 :** Unspecified
+ INPUTSTREAM_COLORTRC_UNSPECIFIED = 2,
+
+ /// @brief **3 :** Reserved
+ INPUTSTREAM_COLORTRC_RESERVED = 3,
+
+ /// @brief **4 :** Also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
+ INPUTSTREAM_COLORTRC_GAMMA22 = 4,
+
+ /// @brief **5 :** Also ITU-R BT470BG
+ INPUTSTREAM_COLORTRC_GAMMA28 = 5,
+
+ /// @brief **6 :** Also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
+ INPUTSTREAM_COLORTRC_SMPTE170M = 6,
+
+ /// @brief **7 :** Functionally identical to above @ref INPUTSTREAM_COLORTRC_SMPTE170M
+ INPUTSTREAM_COLORTRC_SMPTE240M = 7,
+
+ /// @brief **8 :** Linear transfer characteristics
+ INPUTSTREAM_COLORTRC_LINEAR = 8,
+
+ /// @brief **9 :** Logarithmic transfer characteristic (100:1 range)
+ INPUTSTREAM_COLORTRC_LOG = 9,
+
+ /// @brief **10 :** Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)
+ INPUTSTREAM_COLORTRC_LOG_SQRT = 10,
+
+ /// @brief **11 :** IEC 61966-2-4
+ INPUTSTREAM_COLORTRC_IEC61966_2_4 = 11,
+
+ /// @brief **12 :** ITU-R BT1361 Extended Colour Gamut
+ INPUTSTREAM_COLORTRC_BT1361_ECG = 12,
+
+ /// @brief **13 :** IEC 61966-2-1 (sRGB or sYCC)
+ INPUTSTREAM_COLORTRC_IEC61966_2_1 = 13,
+
+ /// @brief **14 :** ITU-R BT2020 for 10-bit system
+ INPUTSTREAM_COLORTRC_BT2020_10 = 14,
+
+ /// @brief **15 :** ITU-R BT2020 for 12-bit system
+ INPUTSTREAM_COLORTRC_BT2020_12 = 15,
+
+ /// @brief **16 :** SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems
+ INPUTSTREAM_COLORTRC_SMPTE2084 = 16,
+
+ /// @brief **16 :** Same as @ref INPUTSTREAM_COLORTRC_SMPTE2084
+ INPUTSTREAM_COLORTRC_SMPTEST2084 = INPUTSTREAM_COLORTRC_SMPTE2084,
+
+ /// @brief **17 :** SMPTE ST 428-1
+ INPUTSTREAM_COLORTRC_SMPTE428 = 17,
+
+ /// @brief **17 :** Same as @ref INPUTSTREAM_COLORTRC_SMPTE428
+ INPUTSTREAM_COLORTRC_SMPTEST428_1 = INPUTSTREAM_COLORTRC_SMPTE428,
+
+ /// @brief **18 :** ARIB STD-B67, known as "Hybrid log-gamma"
+ INPUTSTREAM_COLORTRC_ARIB_STD_B67 = 18,
+
+ /// @brief The maximum value to use in a list.
+ INPUTSTREAM_COLORTRC_MAX
+ };
+ ///@}
+ //------------------------------------------------------------------------------
+
+ /*!
+ * @brief stream properties
+ */
+ struct INPUTSTREAM_INFO
+ {
+ enum INPUTSTREAM_TYPE m_streamType;
+ uint32_t m_features;
+ uint32_t m_flags;
+
+ //! @brief (optional) name of the stream, \0 for default handling
+ char m_name[INPUTSTREAM_MAX_STRING_NAME_SIZE];
+
+ //! @brief (required) name of codec according to ffmpeg
+ char m_codecName[INPUTSTREAM_MAX_STRING_CODEC_SIZE];
+
+ //! @brief (optional) internal name of codec (selectionstream info)
+ char m_codecInternalName[INPUTSTREAM_MAX_STRING_CODEC_SIZE];
+
+ //! @brief (optional) the profile of the codec
+ enum STREAMCODEC_PROFILE m_codecProfile;
+
+ //! @brief (required) physical index
+ unsigned int m_pID;
+
+ const uint8_t* m_ExtraData;
+ unsigned int m_ExtraSize;
+
+ //! @brief RFC 5646 language code (empty string if undefined)
+ char m_language[INPUTSTREAM_MAX_STRING_LANGUAGE_SIZE];
+
+ //! Video stream related data
+ //@{
+
+ //! @brief Scale of 1000 and a rate of 29970 will result in 29.97 fps
+ unsigned int m_FpsScale;
+
+ unsigned int m_FpsRate;
+
+ //! @brief height of the stream reported by the demuxer
+ unsigned int m_Height;
+
+ //! @brief width of the stream reported by the demuxer
+ unsigned int m_Width;
+
+ //! @brief display aspect of stream
+ float m_Aspect;
+
+ //@}
+
+ //! Audio stream related data
+ //@{
+
+ //! @brief (required) amount of channels
+ unsigned int m_Channels;
+
+ //! @brief (required) sample rate
+ unsigned int m_SampleRate;
+
+ //! @brief (required) bit rate
+ unsigned int m_BitRate;
+
+ //! @brief (required) bits per sample
+ unsigned int m_BitsPerSample;
+
+ unsigned int m_BlockAlign;
+
+ //@}
+
+ struct STREAM_CRYPTO_SESSION m_cryptoSession;
+
+ // new in API version 2.0.8
+ //@{
+ //! @brief Codec If available, the fourcc code codec
+ unsigned int m_codecFourCC;
+
+ //! @brief definition of colorspace
+ enum INPUTSTREAM_COLORSPACE m_colorSpace;
+
+ //! @brief color range if available
+ enum INPUTSTREAM_COLORRANGE m_colorRange;
+ //@}
+
+ //new in API 2.0.9 / INPUTSTREAM_VERSION_LEVEL 1
+ //@{
+ enum INPUTSTREAM_COLORPRIMARIES m_colorPrimaries;
+ enum INPUTSTREAM_COLORTRC m_colorTransferCharacteristic;
+ //@}
+
+ //! @brief mastering static Metadata
+ struct INPUTSTREAM_MASTERING_METADATA* m_masteringMetadata;
+
+ //! @brief content light static Metadata
+ struct INPUTSTREAM_CONTENTLIGHT_METADATA* m_contentLightMetadata;
+ };
+
+ struct INPUTSTREAM_TIMES
+ {
+ time_t startTime;
+ double ptsStart;
+ double ptsBegin;
+ double ptsEnd;
+ };
+
+ /*!
+ * @brief "C" ABI Structures to transfer the methods from this to Kodi
+ */
+
+ // this are properties given to the addon on create
+ // at this time we have no parameters for the addon
+ typedef struct AddonProps_InputStream /* internal */
+ {
+ int dummy;
+ } AddonProps_InputStream;
+
+ typedef struct AddonToKodiFuncTable_InputStream /* internal */
+ {
+ KODI_HANDLE kodiInstance;
+ struct DEMUX_PACKET* (*allocate_demux_packet)(void* kodiInstance, int data_size);
+ struct DEMUX_PACKET* (*allocate_encrypted_demux_packet)(void* kodiInstance,
+ unsigned int data_size,
+ unsigned int encrypted_subsample_count);
+ void (*free_demux_packet)(void* kodiInstance, struct DEMUX_PACKET* packet);
+ } AddonToKodiFuncTable_InputStream;
+
+ struct AddonInstance_InputStream;
+ typedef struct KodiToAddonFuncTable_InputStream /* internal */
+ {
+ KODI_HANDLE addonInstance;
+
+ bool(__cdecl* open)(const struct AddonInstance_InputStream* instance,
+ struct INPUTSTREAM_PROPERTY* props);
+ void(__cdecl* close)(const struct AddonInstance_InputStream* instance);
+ const char*(__cdecl* get_path_list)(const struct AddonInstance_InputStream* instance);
+ void(__cdecl* get_capabilities)(const struct AddonInstance_InputStream* instance,
+ struct INPUTSTREAM_CAPABILITIES* capabilities);
+
+ // IDemux
+ bool(__cdecl* get_stream_ids)(const struct AddonInstance_InputStream* instance,
+ struct INPUTSTREAM_IDS* ids);
+ bool(__cdecl* get_stream)(const struct AddonInstance_InputStream* instance,
+ int streamid,
+ struct INPUTSTREAM_INFO* info,
+ KODI_HANDLE* demuxStream,
+ KODI_HANDLE (*transfer_stream)(KODI_HANDLE handle,
+ int streamId,
+ struct INPUTSTREAM_INFO* stream));
+ void(__cdecl* enable_stream)(const struct AddonInstance_InputStream* instance,
+ int streamid,
+ bool enable);
+ bool(__cdecl* open_stream)(const struct AddonInstance_InputStream* instance, int streamid);
+ void(__cdecl* demux_reset)(const struct AddonInstance_InputStream* instance);
+ void(__cdecl* demux_abort)(const struct AddonInstance_InputStream* instance);
+ void(__cdecl* demux_flush)(const struct AddonInstance_InputStream* instance);
+ struct DEMUX_PACKET*(__cdecl* demux_read)(const struct AddonInstance_InputStream* instance);
+ bool(__cdecl* demux_seek_time)(const struct AddonInstance_InputStream* instance,
+ double time,
+ bool backwards,
+ double* startpts);
+ void(__cdecl* demux_set_speed)(const struct AddonInstance_InputStream* instance, int speed);
+ void(__cdecl* set_video_resolution)(const struct AddonInstance_InputStream* instance,
+ unsigned int width,
+ unsigned int height,
+ unsigned int maxWidth,
+ unsigned int maxHeight);
+
+ // IDisplayTime
+ int(__cdecl* get_total_time)(const struct AddonInstance_InputStream* instance);
+ int(__cdecl* get_time)(const struct AddonInstance_InputStream* instance);
+
+ // ITime
+ bool(__cdecl* get_times)(const struct AddonInstance_InputStream* instance,
+ struct INPUTSTREAM_TIMES* times);
+
+ // IPosTime
+ bool(__cdecl* pos_time)(const struct AddonInstance_InputStream* instance, int ms);
+
+ int(__cdecl* read_stream)(const struct AddonInstance_InputStream* instance,
+ uint8_t* buffer,
+ unsigned int bufferSize);
+ int64_t(__cdecl* seek_stream)(const struct AddonInstance_InputStream* instance,
+ int64_t position,
+ int whence);
+ int64_t(__cdecl* position_stream)(const struct AddonInstance_InputStream* instance);
+ int64_t(__cdecl* length_stream)(const struct AddonInstance_InputStream* instance);
+ bool(__cdecl* is_real_time_stream)(const struct AddonInstance_InputStream* instance);
+
+ // IChapter
+ int(__cdecl* get_chapter)(const struct AddonInstance_InputStream* instance);
+ int(__cdecl* get_chapter_count)(const struct AddonInstance_InputStream* instance);
+ const char*(__cdecl* get_chapter_name)(const struct AddonInstance_InputStream* instance,
+ int ch);
+ int64_t(__cdecl* get_chapter_pos)(const struct AddonInstance_InputStream* instance, int ch);
+ bool(__cdecl* seek_chapter)(const struct AddonInstance_InputStream* instance, int ch);
+
+ int(__cdecl* block_size_stream)(const struct AddonInstance_InputStream* instance);
+ } KodiToAddonFuncTable_InputStream;
+
+ typedef struct AddonInstance_InputStream /* internal */
+ {
+ struct AddonProps_InputStream* props;
+ struct AddonToKodiFuncTable_InputStream* toKodi;
+ struct KodiToAddonFuncTable_InputStream* toAddon;
+ } AddonInstance_InputStream;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_INPUTSTREAM_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/CMakeLists.txt
new file mode 100644
index 0000000..c7d9451
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ demux_packet.h
+ stream_codec.h
+ stream_constants.h
+ stream_crypto.h
+ timing_constants.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_addon-instance_inputstream)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/demux_packet.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/demux_packet.h
new file mode 100644
index 0000000..79686ab
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/demux_packet.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_INPUTSTREAM_DEMUXPACKET_H
+#define C_API_ADDONINSTANCE_INPUTSTREAM_DEMUXPACKET_H
+
+#include "timing_constants.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define DEMUX_SPECIALID_STREAMINFO -10
+#define DEMUX_SPECIALID_STREAMCHANGE -11
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ struct DEMUX_CRYPTO_INFO;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_Interface_DEMUX_PACKET struct DEMUX_PACKET
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_Interface
+ /// @brief **Demux packet**\n
+ /// To processed codec and demux inputstream stream.
+ ///
+ /// This part is in the "C" style in order to have better performance and
+ /// possibly to be used in "C" libraries.
+ ///
+ /// The structure should be created with @ref kodi::addon::CInstanceInputStream::AllocateDemuxPacket()
+ /// or @ref kodi::addon::CInstanceInputStream::AllocateEncryptedDemuxPacket()
+ /// and if not added to Kodi with @ref kodi::addon::CInstanceInputStream::FreeDemuxPacket()
+ /// be deleted again.
+ ///
+ /// Packages that have been given to Kodi and processed will then be deleted
+ /// by him.
+ ///
+ ///@{
+ struct DEMUX_PACKET
+ {
+ /// @brief Stream package which is given for decoding.
+ ///
+ /// @note Associated storage from here is created using
+ /// @ref kodi::addon::CInstanceInputStream::AllocateDemuxPacket()
+ /// or @ref kodi::addon::CInstanceInputStream::AllocateEncryptedDemuxPacket().
+ uint8_t* pData;
+
+ /// @brief Size of the package given at @ref pData.
+ int iSize;
+
+ /// @brief Identification of the stream.
+ int iStreamId;
+
+ /// @brief Identification of the associated demuxer, this can be identical
+ /// on several streams.
+ int64_t demuxerId;
+
+ /// @brief The group this data belongs to, used to group data from different
+ /// streams together.
+ int iGroupId;
+
+ //------------------------------------------
+
+ /// @brief Additional packet data that can be provided by the container.
+ ///
+ /// Packet can contain several types of side information.
+ ///
+ /// This is usually based on that of ffmpeg, see
+ /// [AVPacketSideData](https://ffmpeg.org/doxygen/trunk/structAVPacketSideData.html).
+ void* pSideData;
+
+ /// @brief Data elements stored at @ref pSideData.
+ int iSideDataElems;
+
+ //------------------------------------------
+
+ /// @brief Presentation time stamp (PTS).
+ double pts;
+
+ /// @brief Decoding time stamp (DTS).
+ double dts;
+
+ /// @brief Duration in @ref STREAM_TIME_BASE if available
+ double duration;
+
+ /// @brief Display time from input stream
+ int dispTime;
+
+ /// @brief To show that this package allows recreating the presentation by
+ /// mistake.
+ bool recoveryPoint;
+
+ //------------------------------------------
+
+ /// @brief Optional data to allow decryption at processing site if
+ /// necessary.
+ ///
+ /// This can be created using @ref kodi::addon::CInstanceInputStream::AllocateEncryptedDemuxPacket(),
+ /// otherwise this is declared as <b>`nullptr`</b>.
+ ///
+ /// See @ref DEMUX_CRYPTO_INFO for their style.
+ struct DEMUX_CRYPTO_INFO* cryptoInfo;
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_INPUTSTREAM_DEMUXPACKET_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_codec.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_codec.h
new file mode 100644
index 0000000..91789e7
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_codec.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2017-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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCODEC_H
+#define C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCODEC_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //==============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_StreamEncryption_STREAMCODEC_PROFILE enum STREAMCODEC_PROFILE
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_StreamCodec
+ /// @brief **The standard defines several sets of capabilities.**\n
+ /// Which are referred to as profiles, targeting specific classes of applications.
+ ///
+ ///@{
+ enum STREAMCODEC_PROFILE
+ {
+ /// @brief Unknown codec profile
+ CodecProfileUnknown = 0,
+
+ /// @brief If a codec profile is not required
+ CodecProfileNotNeeded,
+
+ /// @brief **H264** Baseline Profile (BP, 66)\n
+ /// \n
+ /// Primarily for low-cost applications that require additional data loss
+ /// robustness, this profile is used in some videoconferencing and mobile
+ /// applications. This profile includes all features that are supported
+ /// in the Constrained Baseline Profile, plus three additional features
+ /// that can be used for loss robustness (or for other purposes such as
+ /// low-delay multi-point video stream compositing). The importance of
+ /// this profile has faded somewhat since the definition of the Constrained
+ /// Baseline Profile in 2009. All Constrained Baseline Profile bitstreams
+ /// are also considered to be Baseline Profile bitstreams, as these two
+ /// profiles share the same profile identifier code value.
+ H264CodecProfileBaseline,
+
+ /// @brief **H264** Main Profile (MP, 77)\n
+ /// \n
+ /// This profile is used for standard-definition digital TV broadcasts that
+ /// use the MPEG-4 format as defined in the
+ /// [DVB standard](http://www.etsi.org/deliver/etsi_ts/101100_101199/101154/01.09.01_60/ts_101154v010901p.pdf).
+ /// It is not, however, used for high-definition television broadcasts, as the
+ /// importance of this profile faded when the High Profile was developed
+ /// in 2004 for that application.
+ H264CodecProfileMain,
+
+ /// @brief **H264** Extended Profile (XP, 88)\n
+ /// \n
+ /// Intended as the streaming video profile, this profile has relatively high
+ /// compression capability and some extra tricks for robustness to data losses
+ /// and server stream switching.
+ H264CodecProfileExtended,
+
+ /// @brief **H264** High Profile (HiP, 100)\n
+ /// \n
+ /// The primary profile for broadcast and disc storage applications,
+ /// particularly for high-definition television applications (for example,
+ /// this is the profile adopted by the [Blu-ray Disc](https://en.wikipedia.org/wiki/Blu-ray_Disc)
+ /// storage format and the [DVB](https://en.wikipedia.org/wiki/Digital_Video_Broadcasting)
+ /// HDTV broadcast service).
+ H264CodecProfileHigh,
+
+ /// @brief **H264** High 10 Profile (Hi10P, 110)\n
+ /// \n
+ /// Going beyond typical mainstream consumer product capabilities, this
+ /// profile builds on top of the High Profile, adding support for up to 10
+ /// bits per sample of decoded picture precision.
+ H264CodecProfileHigh10,
+
+ /// @brief **H264** High 4:2:2 Profile (Hi422P, 122)\n
+ /// \n
+ /// Primarily targeting professional applications that use interlaced video,
+ /// this profile builds on top of the High 10 Profile, adding support for the
+ /// 4:2:2 chroma sampling format while using up to 10 bits per sample of
+ /// decoded picture precision.
+ H264CodecProfileHigh422,
+
+ /// @brief **H264** High 4:4:4 Predictive Profile (Hi444PP, 244)\n
+ /// \n
+ /// This profile builds on top of the High 4:2:2 Profile, supporting up to
+ /// 4:4:4 chroma sampling, up to 14 bits per sample, and additionally
+ /// supporting efficient lossless region coding and the coding of each
+ /// picture as three separate color planes.
+ H264CodecProfileHigh444Predictive,
+
+ /// @brief **VP9** profile 0\n
+ /// \n
+ /// There are several variants of the VP9 format (known as "coding profiles"),
+ /// which successively allow more features; profile 0 is the basic variant,
+ /// requiring the least from a hardware implementation.
+ ///
+ /// [Color depth](https://en.wikipedia.org/wiki/Color_depth): 8 bit/sample,
+ /// [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling): 4:2:0
+ VP9CodecProfile0 = 20,
+
+ /// @brief **VP9** profile 1\n
+ /// \n
+ /// [Color depth](https://en.wikipedia.org/wiki/Color_depth): 8 bit,
+ /// [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling): 4:2:0, 4:2:2, 4:4:4
+ VP9CodecProfile1,
+
+ /// @brief **VP9** profile 2\n
+ /// \n
+ /// [Color depth](https://en.wikipedia.org/wiki/Color_depth): 10–12 bit,
+ /// [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling): 4:2:0
+ VP9CodecProfile2,
+
+ /// @brief **VP9** profile 3\n
+ /// \n
+ /// [Color depth](https://en.wikipedia.org/wiki/Color_depth): 10–12 bit,
+ /// [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling): 4:2:0, 4:2:2, 4:4:4,
+ /// see [VP9 Bitstream & Decoding Process Specification](https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp9-bitstream-specification-v0.6-20160331-draft.pdf)
+ VP9CodecProfile3,
+
+ /// @brief **AV1** Main profile\n
+ /// \n
+ /// [Color depth](https://en.wikipedia.org/wiki/Color_depth): 8–10 bit,
+ /// [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling): 4:2:0
+ /// see [AV1 specification](https://aomedia.org/av1/specification/)
+ AV1CodecProfileMain,
+
+ /// @brief **AV1** High profile\n
+ /// \n
+ /// [Color depth](https://en.wikipedia.org/wiki/Color_depth): 8–10 bit,
+ /// [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling): 4:2:0, 4:4:4
+ /// see [AV1 specification](https://aomedia.org/av1/specification/)
+ AV1CodecProfileHigh,
+
+ /// @brief **AV1** Professional profile\n
+ /// \n
+ /// [Color depth](https://en.wikipedia.org/wiki/Color_depth): 8–12 bit,
+ /// [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling): 4:2:0, 4:2:2, 4:4:4
+ /// see [AV1 specification](https://aomedia.org/av1/specification/)
+ AV1CodecProfileProfessional,
+ };
+ ///@}
+ //------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCODEC_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_constants.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_constants.h
new file mode 100644
index 0000000..8c12c26
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_constants.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017-2020 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCONSTANTS_H
+#define C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCONSTANTS_H
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_StreamConstants
+/// @brief The name of the inputstream add-on that should be used by Kodi to
+/// play the stream.
+///
+/// Leave blank to use Kodi's built-in playing capabilities or to allow
+/// ffmpeg to handle directly set to @ref STREAM_PROPERTY_VALUE_INPUTSTREAMFFMPEG.
+#define STREAM_PROPERTY_INPUTSTREAM "inputstream"
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_StreamConstants
+/// @brief The name of the default player to use for this inputstream add-on that
+/// should be used by Kodi to play the stream.
+///
+/// Leave blank to use Kodi's built-in player selection mechanism.
+/// Permitted values are:
+/// - "videodefaultplayer"
+/// - "audiodefaultplayer"
+#define STREAM_PROPERTY_INPUTSTREAM_PLAYER "inputstream-player"
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_StreamConstants
+/// @brief Identification string for an input stream.
+///
+/// This value can be used in addition to @ref STREAM_PROPERTY_INPUTSTREAM. It is
+/// used to provide the respective inpustream addon with additional
+/// identification.
+///
+/// The difference between this and other stream properties is that it is also
+/// passed in the associated @ref kodi::addon::CAddonBase::CreateInstance call.
+///
+/// This makes it possible to select different processing classes within the
+/// associated add-on.
+#define STREAM_PROPERTY_INPUTSTREAM_INSTANCE_ID "inputstream-instance-id"
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_StreamConstants
+/// @brief "true" to denote that the stream that should be played is a
+/// realtime stream. Any other value indicates that this is not a realtime
+/// stream.
+#define STREAM_PROPERTY_ISREALTIMESTREAM "isrealtimestream"
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_StreamConstants
+/// @brief Special value for @ref STREAM_PROPERTY_INPUTSTREAM to use
+/// ffmpeg to directly play a stream URL.
+#define STREAM_PROPERTY_VALUE_INPUTSTREAMFFMPEG "inputstream.ffmpeg"
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_StreamConstants
+/// @brief Max number of properties that can be sent to an Inputstream addon
+#define STREAM_MAX_PROPERTY_COUNT 30
+
+#endif /* !C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCONSTANTS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_crypto.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_crypto.h
new file mode 100644
index 0000000..3d4f621
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/stream_crypto.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2017-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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCRYPTO_H
+#define C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCRYPTO_H
+
+#include <stdint.h>
+#include <string.h>
+
+#define STREAMCRYPTO_VERSION_LEVEL 2
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_StreamEncryption_STREAM_CRYPTO_KEY_SYSTEM enum STREAM_CRYPTO_KEY_SYSTEM
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_StreamEncryption
+ /// @brief **Available ways to process stream cryptography**\n
+ /// For @ref cpp_kodi_addon_inputstream_Defs_StreamEncryption_StreamCryptoSession,
+ /// this defines the used and required auxiliary modules which are required to
+ /// process the encryption stream.
+ ///
+ /// Used to set wanted [digital rights management](https://en.wikipedia.org/wiki/Digital_rights_management)
+ /// (DRM) technology provider for stream.
+ ///@{
+ enum STREAM_CRYPTO_KEY_SYSTEM
+ {
+ /// @brief **0** - If no path is to be used, this is the default
+ STREAM_CRYPTO_KEY_SYSTEM_NONE = 0,
+
+ /// @brief **1** - To use [Widevine](https://en.wikipedia.org/wiki/Widevine) for processing
+ STREAM_CRYPTO_KEY_SYSTEM_WIDEVINE,
+
+ /// @brief **2** - To use [Playready](https://en.wikipedia.org/wiki/PlayReady) for processing
+ STREAM_CRYPTO_KEY_SYSTEM_PLAYREADY,
+
+ /// @brief **3** - To use Wiseplay for processing
+ STREAM_CRYPTO_KEY_SYSTEM_WISEPLAY,
+
+ /// @brief **4** - The maximum value to use in a list.
+ STREAM_CRYPTO_KEY_SYSTEM_COUNT
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_StreamEncryption_STREAM_CRYPTO_FLAGS enum STREAM_CRYPTO_FLAGS
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_StreamEncryption
+ /// @brief **Cryptography flags to use special conditions**\n
+ /// To identify special extra conditions.
+ ///
+ /// @note These variables are bit flags which are created using "|" can be used
+ /// together.
+ ///
+ ///@{
+ enum STREAM_CRYPTO_FLAGS
+ {
+ /// @brief **0000 0000** - Empty to set if nothing is used.
+ STREAM_CRYPTO_FLAG_NONE = 0,
+
+ /// @brief **0000 0001** - Is set in flags if decoding has to be done in
+ /// [trusted execution environment (TEE)](https://en.wikipedia.org/wiki/Trusted_execution_environment).
+ STREAM_CRYPTO_FLAG_SECURE_DECODER = (1 << 0)
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_inputstream_Defs_StreamEncryption_DEMUX_CRYPTO_INFO struct DEMUX_CRYPTO_INFO
+ /// @ingroup cpp_kodi_addon_inputstream_Defs_StreamEncryption
+ /// @brief **C data structure for processing encrypted streams.**\n
+ /// If required, this structure is used for every DEMUX_PACKET to be processed.
+ ///
+ ///@{
+ struct DEMUX_CRYPTO_INFO
+ {
+ /// @brief Number of subsamples.
+ uint16_t numSubSamples;
+
+ /// @brief Flags for later use.
+ uint16_t flags;
+
+ /// @brief @ref numSubSamples uint16_t's which define the size of clear size
+ /// of a subsample.
+ uint16_t* clearBytes;
+
+ /// @brief @ref numSubSamples uint32_t's which define the size of cipher size
+ /// of a subsample.
+ uint32_t* cipherBytes;
+
+ /// @brief Initialization vector
+ uint8_t iv[16];
+
+ /// @brief Key id
+ uint8_t kid[16];
+
+ /// @brief Encryption mode
+ uint16_t mode;
+
+ /// @brief Crypt blocks - number of blocks to encrypt in sample encryption pattern
+ uint8_t cryptBlocks;
+
+ /// @brief Skip blocks - number of blocks to skip in sample encryption pattern
+ uint8_t skipBlocks;
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ // Data to manage stream cryptography
+ struct STREAM_CRYPTO_SESSION
+ {
+ // keysystem for encrypted media, STREAM_CRYPTO_KEY_SYSTEM_NONE for unencrypted
+ // media.
+ //
+ // See STREAM_CRYPTO_KEY_SYSTEM for available options.
+ enum STREAM_CRYPTO_KEY_SYSTEM keySystem;
+
+ // Flags to use special conditions, see STREAM_CRYPTO_FLAGS for available flags.
+ uint8_t flags;
+
+ // The crypto session key id.
+ char sessionId[256];
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_INPUTSTREAM_STREAMCRYPTO_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/timing_constants.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/timing_constants.h
new file mode 100644
index 0000000..a226a0d
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream/timing_constants.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015-2020 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_INPUTSTREAM_TIMINGCONSTANTS_H
+#define C_API_ADDONINSTANCE_INPUTSTREAM_TIMINGCONSTANTS_H
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_TimingConstants
+/// @brief Speed value to pause stream in playback.
+///
+#define STREAM_PLAYSPEED_PAUSE 0 // frame stepping
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_TimingConstants
+/// @brief Speed value to perform stream playback at normal speed.
+///
+/// See @ref STREAM_PLAYSPEED_PAUSE for pause of stream.
+///
+#define STREAM_PLAYSPEED_NORMAL 1000
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_TimingConstants
+/// @brief Time base represented as integer.
+///
+#define STREAM_TIME_BASE 1000000
+
+/// @ingroup cpp_kodi_addon_inputstream_Defs_TimingConstants
+/// @brief Undefined timestamp value.
+///
+/// Usually reported by demuxer that work on containers that do not provide
+/// either pts or dts.
+///
+#define STREAM_NOPTS_VALUE 0xFFF0000000000000
+
+// "C" defines to translate stream times
+#define STREAM_TIME_TO_MSEC(x) ((int)((double)(x)*1000 / STREAM_TIME_BASE))
+#define STREAM_SEC_TO_TIME(x) ((double)(x)*STREAM_TIME_BASE)
+#define STREAM_MSEC_TO_TIME(x) ((double)(x)*STREAM_TIME_BASE / 1000)
+
+#endif /* !C_API_ADDONINSTANCE_INPUTSTREAM_TIMINGCONSTANTS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/peripheral.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/peripheral.h
new file mode 100644
index 0000000..d5e1d2b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/peripheral.h
@@ -0,0 +1,707 @@
+/*
+ * Copyright (C) 2014-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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PERIPHERAL_H
+#define C_API_ADDONINSTANCE_PERIPHERAL_H
+
+#include "../addon_base.h"
+
+/* indicates a joystick has no preference for port number */
+#define NO_PORT_REQUESTED (-1)
+
+/* joystick's driver button/hat/axis index is unknown */
+#define DRIVER_INDEX_UNKNOWN (-1)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_General_PERIPHERAL_ERROR enum PERIPHERAL_ERROR
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_General
+ /// @brief **Peripheral add-on error codes**\n
+ /// Used as return values on most peripheral related functions.
+ ///
+ /// In this way, a peripheral instance signals errors in its processing and,
+ /// under certain conditions, allows Kodi to make corrections.
+ ///
+ ///@{
+ typedef enum PERIPHERAL_ERROR
+ {
+ /// @brief __0__ : No error occurred
+ PERIPHERAL_NO_ERROR = 0,
+
+ /// @brief __-1__ : An unknown error occurred
+ PERIPHERAL_ERROR_UNKNOWN = -1,
+
+ /// @brief __-2__ : The command failed
+ PERIPHERAL_ERROR_FAILED = -2,
+
+ /// @brief __-3__ : The parameters of the method are invalid for this operation
+ PERIPHERAL_ERROR_INVALID_PARAMETERS = -3,
+
+ /// @brief __-4__ : The method that the frontend called is not implemented
+ PERIPHERAL_ERROR_NOT_IMPLEMENTED = -4,
+
+ /// @brief __-5__ : No peripherals are connected
+ PERIPHERAL_ERROR_NOT_CONNECTED = -5,
+
+ /// @brief __-6__ : Peripherals are connected, but command was interrupted
+ PERIPHERAL_ERROR_CONNECTION_FAILED = -6,
+ } PERIPHERAL_ERROR;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ // @name Peripheral types
+ //{
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Peripheral_PERIPHERAL_TYPE enum PERIPHERAL_TYPE
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Peripheral
+ /// @brief **Peripheral types**\n
+ /// Types used to identify wanted peripheral.
+ ///@{
+ typedef enum PERIPHERAL_TYPE
+ {
+ /// @brief Type declared as unknown.
+ PERIPHERAL_TYPE_UNKNOWN,
+
+ /// @brief Type declared as joystick.
+ PERIPHERAL_TYPE_JOYSTICK,
+
+ /// @brief Type declared as keyboard.
+ PERIPHERAL_TYPE_KEYBOARD,
+ } PERIPHERAL_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Information shared between peripherals
+ */
+ typedef struct PERIPHERAL_INFO
+ {
+ PERIPHERAL_TYPE type; /*!< type of peripheral */
+ char* name; /*!< name of peripheral */
+ uint16_t vendor_id; /*!< vendor ID of peripheral, 0x0000 if unknown */
+ uint16_t product_id; /*!< product ID of peripheral, 0x0000 if unknown */
+ unsigned int index; /*!< the order in which the add-on identified this peripheral */
+ } ATTR_PACKED PERIPHERAL_INFO;
+
+ /*!
+ * @brief Peripheral add-on capabilities.
+ */
+ typedef struct PERIPHERAL_CAPABILITIES
+ {
+ bool provides_joysticks; /*!< true if the add-on provides joysticks */
+ bool provides_joystick_rumble;
+ bool provides_joystick_power_off;
+ bool provides_buttonmaps; /*!< true if the add-on provides button maps */
+ } ATTR_PACKED PERIPHERAL_CAPABILITIES;
+
+ //}
+
+ // @name Event types
+ //{
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Event_PERIPHERAL_EVENT_TYPE enum PERIPHERAL_EVENT_TYPE
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Event
+ /// @brief **Event types**\n
+ /// Types of events that can be sent and received.
+ ///@{
+ typedef enum PERIPHERAL_EVENT_TYPE
+ {
+ /// @brief unknown event
+ PERIPHERAL_EVENT_TYPE_NONE,
+
+ /// @brief state changed for joystick driver button
+ PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON,
+
+ /// @brief state changed for joystick driver hat
+ PERIPHERAL_EVENT_TYPE_DRIVER_HAT,
+
+ /// @brief state changed for joystick driver axis
+ PERIPHERAL_EVENT_TYPE_DRIVER_AXIS,
+
+ /// @brief set the state for joystick rumble motor
+ PERIPHERAL_EVENT_TYPE_SET_MOTOR,
+ } PERIPHERAL_EVENT_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Event_JOYSTICK_STATE_BUTTON enum JOYSTICK_STATE_BUTTON
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Event
+ /// @brief **State button**\n
+ /// States a button can have
+ ///@{
+ typedef enum JOYSTICK_STATE_BUTTON
+ {
+ /// @brief button is released
+ JOYSTICK_STATE_BUTTON_UNPRESSED = 0x0,
+
+ /// @brief button is pressed
+ JOYSTICK_STATE_BUTTON_PRESSED = 0x1,
+ } JOYSTICK_STATE_BUTTON;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Event_JOYSTICK_STATE_HAT enum JOYSTICK_STATE_HAT
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Event
+ /// @brief **State hat**\n
+ /// States a D-pad (also called a hat) can have
+ ///@{
+ typedef enum JOYSTICK_STATE_HAT
+ {
+ /// @brief no directions are pressed
+ JOYSTICK_STATE_HAT_UNPRESSED = 0x0,
+
+ /// @brief only left is pressed
+ JOYSTICK_STATE_HAT_LEFT = 0x1,
+
+ /// @brief only right is pressed
+ JOYSTICK_STATE_HAT_RIGHT = 0x2,
+
+ /// @brief only up is pressed
+ JOYSTICK_STATE_HAT_UP = 0x4,
+
+ /// @brief only down is pressed
+ JOYSTICK_STATE_HAT_DOWN = 0x8,
+
+ /// @brief left and up is pressed
+ JOYSTICK_STATE_HAT_LEFT_UP = JOYSTICK_STATE_HAT_LEFT | JOYSTICK_STATE_HAT_UP,
+
+ /// @brief left and down is pressed
+ JOYSTICK_STATE_HAT_LEFT_DOWN = JOYSTICK_STATE_HAT_LEFT | JOYSTICK_STATE_HAT_DOWN,
+
+ /// @brief right and up is pressed
+ JOYSTICK_STATE_HAT_RIGHT_UP = JOYSTICK_STATE_HAT_RIGHT | JOYSTICK_STATE_HAT_UP,
+
+ /// @brief right and down is pressed
+ JOYSTICK_STATE_HAT_RIGHT_DOWN = JOYSTICK_STATE_HAT_RIGHT | JOYSTICK_STATE_HAT_DOWN,
+ } JOYSTICK_STATE_HAT;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Event
+ /// @brief Axis value in the closed interval [-1.0, 1.0]
+ ///
+ /// The axis state uses the XInput coordinate system:
+ /// - Negative values signify down or to the left
+ /// - Positive values signify up or to the right
+ ///
+ typedef float JOYSTICK_STATE_AXIS;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Event
+ /// @brief Motor value in the closed interval [0.0, 1.0]
+ typedef float JOYSTICK_STATE_MOTOR;
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Event information
+ */
+ typedef struct PERIPHERAL_EVENT
+ {
+ /*! @brief Index of the peripheral handling/receiving the event */
+ unsigned int peripheral_index;
+
+ /*! @brief Type of the event used to determine which enum field to access below */
+ PERIPHERAL_EVENT_TYPE type;
+
+ /*! @brief The index of the event source */
+ unsigned int driver_index;
+
+ JOYSTICK_STATE_BUTTON driver_button_state;
+ JOYSTICK_STATE_HAT driver_hat_state;
+ JOYSTICK_STATE_AXIS driver_axis_state;
+ JOYSTICK_STATE_MOTOR motor_state;
+ } ATTR_PACKED PERIPHERAL_EVENT;
+
+ //}
+
+ // @name Joystick types
+ //{
+
+ /*!
+ * @brief Info specific to joystick peripherals
+ */
+ typedef struct JOYSTICK_INFO
+ {
+ PERIPHERAL_INFO peripheral; /*!< @brief peripheral info for this joystick */
+ char* provider; /*!< @brief name of the driver or interface providing the joystick */
+ int requested_port; /*!< @brief requested port number (such as for 360 controllers), or NO_PORT_REQUESTED */
+ unsigned int button_count; /*!< @brief number of buttons reported by the driver */
+ unsigned int hat_count; /*!< @brief number of hats reported by the driver */
+ unsigned int axis_count; /*!< @brief number of axes reported by the driver */
+ unsigned int motor_count; /*!< @brief number of motors reported by the driver */
+ bool supports_poweroff; /*!< @brief whether the joystick supports being powered off */
+ } ATTR_PACKED JOYSTICK_INFO;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JOYSTICK_DRIVER_PRIMITIVE_TYPE enum JOYSTICK_DRIVER_PRIMITIVE_TYPE
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+ /// @brief **Driver primitive type**\n
+ /// Driver input primitives
+ ///
+ /// Mapping lower-level driver values to higher-level controller features is
+ /// non-injective; two triggers can share a single axis.
+ ///
+ /// To handle this, driver values are subdivided into "primitives" that map
+ /// injectively to higher-level features.
+ ///
+ ///@{
+ typedef enum JOYSTICK_DRIVER_PRIMITIVE_TYPE
+ {
+ /// @brief Driver input primitive type unknown
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN,
+
+ /// @brief Driver input primitive type button
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON,
+
+ /// @brief Driver input primitive type hat direction
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION,
+
+ /// @brief Driver input primitive type semiaxis
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS,
+
+ /// @brief Driver input primitive type motor
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR,
+
+ /// @brief Driver input primitive type key
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY,
+
+ /// @brief Driver input primitive type mouse button
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON,
+
+ /// @brief Driver input primitive type relative pointer direction
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION,
+ } JOYSTICK_DRIVER_PRIMITIVE_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Button primitive
+ */
+ typedef struct JOYSTICK_DRIVER_BUTTON
+ {
+ int index;
+ } ATTR_PACKED JOYSTICK_DRIVER_BUTTON;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JOYSTICK_DRIVER_HAT_DIRECTION enum JOYSTICK_DRIVER_HAT_DIRECTION
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+ /// @brief **Driver direction**\n
+ /// Hat direction.
+ ///@{
+ typedef enum JOYSTICK_DRIVER_HAT_DIRECTION
+ {
+ /// @brief Driver hat unknown
+ JOYSTICK_DRIVER_HAT_UNKNOWN,
+
+ /// @brief Driver hat left
+ JOYSTICK_DRIVER_HAT_LEFT,
+
+ /// @brief Driver hat right
+ JOYSTICK_DRIVER_HAT_RIGHT,
+
+ /// @brief Driver hat up
+ JOYSTICK_DRIVER_HAT_UP,
+
+ /// @brief Driver hat down
+ JOYSTICK_DRIVER_HAT_DOWN,
+ } JOYSTICK_DRIVER_HAT_DIRECTION;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Hat direction primitive
+ */
+ typedef struct JOYSTICK_DRIVER_HAT
+ {
+ int index;
+ JOYSTICK_DRIVER_HAT_DIRECTION direction;
+ } ATTR_PACKED JOYSTICK_DRIVER_HAT;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JOYSTICK_DRIVER_SEMIAXIS_DIRECTION enum JOYSTICK_DRIVER_SEMIAXIS_DIRECTION
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+ /// @brief **Driver direction**\n
+ /// Semiaxis direction.
+ ///@{
+ typedef enum JOYSTICK_DRIVER_SEMIAXIS_DIRECTION
+ {
+ /// @brief negative half of the axis
+ JOYSTICK_DRIVER_SEMIAXIS_NEGATIVE = -1,
+
+ /// @brief unknown direction
+ JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN = 0,
+
+ /// @brief positive half of the axis
+ JOYSTICK_DRIVER_SEMIAXIS_POSITIVE = 1,
+ } JOYSTICK_DRIVER_SEMIAXIS_DIRECTION;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Semiaxis primitive
+ */
+ typedef struct JOYSTICK_DRIVER_SEMIAXIS
+ {
+ int index;
+ int center;
+ JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction;
+ unsigned int range;
+ } ATTR_PACKED JOYSTICK_DRIVER_SEMIAXIS;
+
+ /*!
+ * @brief Motor primitive
+ */
+ typedef struct JOYSTICK_DRIVER_MOTOR
+ {
+ int index;
+ } ATTR_PACKED JOYSTICK_DRIVER_MOTOR;
+
+ /*!
+ * @brief Keyboard key primitive
+ */
+ typedef struct JOYSTICK_DRIVER_KEY
+ {
+ char keycode[16];
+ } ATTR_PACKED JOYSTICK_DRIVER_KEY;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JOYSTICK_DRIVER_MOUSE_INDEX enum JOYSTICK_DRIVER_MOUSE_INDEX
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+ /// @brief **Buttons**\n
+ /// Mouse buttons.
+ ///@{
+ typedef enum JOYSTICK_DRIVER_MOUSE_INDEX
+ {
+ /// @brief Mouse index unknown
+ JOYSTICK_DRIVER_MOUSE_INDEX_UNKNOWN,
+
+ /// @brief Mouse index left
+ JOYSTICK_DRIVER_MOUSE_INDEX_LEFT,
+
+ /// @brief Mouse index right
+ JOYSTICK_DRIVER_MOUSE_INDEX_RIGHT,
+
+ /// @brief Mouse index middle
+ JOYSTICK_DRIVER_MOUSE_INDEX_MIDDLE,
+
+ /// @brief Mouse index button 4
+ JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON4,
+
+ /// @brief Mouse index button 5
+ JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON5,
+
+ /// @brief Mouse index wheel up
+ JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_UP,
+
+ /// @brief Mouse index wheel down
+ JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_DOWN,
+
+ /// @brief Mouse index horizontal wheel left
+ JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_LEFT,
+
+ /// @brief Mouse index horizontal wheel right
+ JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_RIGHT,
+ } JOYSTICK_DRIVER_MOUSE_INDEX;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Mouse button primitive
+ */
+ typedef struct JOYSTICK_DRIVER_MOUSE_BUTTON
+ {
+ JOYSTICK_DRIVER_MOUSE_INDEX button;
+ } ATTR_PACKED JOYSTICK_DRIVER_MOUSE_BUTTON;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JOYSTICK_DRIVER_RELPOINTER_DIRECTION enum JOYSTICK_DRIVER_RELPOINTER_DIRECTION
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+ /// @brief **Pointer direction**\n
+ /// Relative pointer direction
+ ///@{
+ typedef enum JOYSTICK_DRIVER_RELPOINTER_DIRECTION
+ {
+ /// @brief Relative pointer direction unknown
+ JOYSTICK_DRIVER_RELPOINTER_UNKNOWN,
+
+ /// @brief Relative pointer direction left
+ JOYSTICK_DRIVER_RELPOINTER_LEFT,
+
+ /// @brief Relative pointer direction right
+ JOYSTICK_DRIVER_RELPOINTER_RIGHT,
+
+ /// @brief Relative pointer direction up
+ JOYSTICK_DRIVER_RELPOINTER_UP,
+
+ /// @brief Relative pointer direction down
+ JOYSTICK_DRIVER_RELPOINTER_DOWN,
+ } JOYSTICK_DRIVER_RELPOINTER_DIRECTION;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Relative pointer direction primitive
+ */
+ typedef struct JOYSTICK_DRIVER_RELPOINTER
+ {
+ JOYSTICK_DRIVER_RELPOINTER_DIRECTION direction;
+ } ATTR_PACKED JOYSTICK_DRIVER_RELPOINTER;
+
+ /*!
+ * @brief Driver primitive struct
+ */
+ typedef struct JOYSTICK_DRIVER_PRIMITIVE
+ {
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE type;
+ union
+ {
+ struct JOYSTICK_DRIVER_BUTTON button;
+ struct JOYSTICK_DRIVER_HAT hat;
+ struct JOYSTICK_DRIVER_SEMIAXIS semiaxis;
+ struct JOYSTICK_DRIVER_MOTOR motor;
+ struct JOYSTICK_DRIVER_KEY key;
+ struct JOYSTICK_DRIVER_MOUSE_BUTTON mouse;
+ struct JOYSTICK_DRIVER_RELPOINTER relpointer;
+ };
+ } ATTR_PACKED JOYSTICK_DRIVER_PRIMITIVE;
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JOYSTICK_FEATURE_TYPE enum JOYSTICK_FEATURE_TYPE
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+ /// @brief **Feature type**\n
+ /// Controller feature.
+ ///
+ /// Controller features are an abstraction over driver values. Each feature
+ /// maps to one or more driver primitives.
+ ///
+ ///@{
+ typedef enum JOYSTICK_FEATURE_TYPE
+ {
+ /// @brief Unknown type
+ JOYSTICK_FEATURE_TYPE_UNKNOWN,
+
+ /// @brief Type scalar
+ JOYSTICK_FEATURE_TYPE_SCALAR,
+
+ /// @brief Type analog stick
+ JOYSTICK_FEATURE_TYPE_ANALOG_STICK,
+
+ /// @brief Type accelerometer
+ JOYSTICK_FEATURE_TYPE_ACCELEROMETER,
+
+ /// @brief Type motor
+ JOYSTICK_FEATURE_TYPE_MOTOR,
+
+ /// @brief Type relative pointer
+ JOYSTICK_FEATURE_TYPE_RELPOINTER,
+
+ /// @brief Type absolute pointer
+ JOYSTICK_FEATURE_TYPE_ABSPOINTER,
+
+ /// @brief Type wheel
+ JOYSTICK_FEATURE_TYPE_WHEEL,
+
+ /// @brief Type throttle
+ JOYSTICK_FEATURE_TYPE_THROTTLE,
+
+ /// @brief Type key
+ JOYSTICK_FEATURE_TYPE_KEY,
+ } JOYSTICK_FEATURE_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick_JOYSTICK_FEATURE_PRIMITIVE enum JOYSTICK_FEATURE_PRIMITIVE
+ /// @ingroup cpp_kodi_addon_peripheral_Defs_Joystick
+ /// @brief **Feature primitives**\n
+ /// Indices used to access a feature's driver primitives.
+ ///
+ ///@{
+ typedef enum JOYSTICK_FEATURE_PRIMITIVE
+ {
+ /// @brief Scalar feature (a button, hat direction or semiaxis)
+ JOYSTICK_SCALAR_PRIMITIVE = 0,
+
+ /// @brief Analog stick up
+ JOYSTICK_ANALOG_STICK_UP = 0,
+ /// @brief Analog stick down
+ JOYSTICK_ANALOG_STICK_DOWN = 1,
+ /// @brief Analog stick right
+ JOYSTICK_ANALOG_STICK_RIGHT = 2,
+ /// @brief Analog stick left
+ JOYSTICK_ANALOG_STICK_LEFT = 3,
+
+ /// @brief Accelerometer X
+ JOYSTICK_ACCELEROMETER_POSITIVE_X = 0,
+ /// @brief Accelerometer Y
+ JOYSTICK_ACCELEROMETER_POSITIVE_Y = 1,
+ /// @brief Accelerometer Z
+ JOYSTICK_ACCELEROMETER_POSITIVE_Z = 2,
+
+ /// @brief Motor
+ JOYSTICK_MOTOR_PRIMITIVE = 0,
+
+ /// @brief Wheel left
+ JOYSTICK_WHEEL_LEFT = 0,
+ /// @brief Wheel right
+ JOYSTICK_WHEEL_RIGHT = 1,
+
+ /// @brief Throttle up
+ JOYSTICK_THROTTLE_UP = 0,
+ /// @brief Throttle down
+ JOYSTICK_THROTTLE_DOWN = 1,
+
+ /// @brief Key
+ JOYSTICK_KEY_PRIMITIVE = 0,
+
+ /// @brief Mouse button
+ JOYSTICK_MOUSE_BUTTON = 0,
+
+ /// @brief Relative pointer direction up
+ JOYSTICK_RELPOINTER_UP = 0,
+ /// @brief Relative pointer direction down
+ JOYSTICK_RELPOINTER_DOWN = 1,
+ /// @brief Relative pointer direction right
+ JOYSTICK_RELPOINTER_RIGHT = 2,
+ /// @brief Relative pointer direction left
+ JOYSTICK_RELPOINTER_LEFT = 3,
+
+ /// @brief Maximum number of primitives
+ JOYSTICK_PRIMITIVE_MAX = 4,
+ } JOYSTICK_FEATURE_PRIMITIVE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Mapping between higher-level controller feature and its driver primitives
+ */
+ typedef struct JOYSTICK_FEATURE
+ {
+ char* name;
+ JOYSTICK_FEATURE_TYPE type;
+ struct JOYSTICK_DRIVER_PRIMITIVE primitives[JOYSTICK_PRIMITIVE_MAX];
+ } ATTR_PACKED JOYSTICK_FEATURE;
+ //}
+
+ typedef struct AddonProps_Peripheral
+ {
+ const char* user_path; /*!< @brief path to the user profile */
+ const char* addon_path; /*!< @brief path to this add-on */
+ } ATTR_PACKED AddonProps_Peripheral;
+
+ struct AddonInstance_Peripheral;
+
+ typedef struct AddonToKodiFuncTable_Peripheral
+ {
+ KODI_HANDLE kodiInstance;
+ void (*trigger_scan)(void* kodiInstance);
+ void (*refresh_button_maps)(void* kodiInstance,
+ const char* device_name,
+ const char* controller_id);
+ unsigned int (*feature_count)(void* kodiInstance,
+ const char* controller_id,
+ JOYSTICK_FEATURE_TYPE type);
+ JOYSTICK_FEATURE_TYPE(*feature_type)
+ (void* kodiInstance, const char* controller_id, const char* feature_name);
+ } AddonToKodiFuncTable_Peripheral;
+
+ //! @todo Mouse, light gun, multitouch
+
+ typedef struct KodiToAddonFuncTable_Peripheral
+ {
+ KODI_HANDLE addonInstance;
+
+ void(__cdecl* get_capabilities)(const struct AddonInstance_Peripheral* addonInstance,
+ struct PERIPHERAL_CAPABILITIES* capabilities);
+ PERIPHERAL_ERROR(__cdecl* perform_device_scan)
+ (const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int* peripheral_count,
+ struct PERIPHERAL_INFO** scan_results);
+ void(__cdecl* free_scan_results)(const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int peripheral_count,
+ struct PERIPHERAL_INFO* scan_results);
+ PERIPHERAL_ERROR(__cdecl* get_events)
+ (const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int* event_count,
+ struct PERIPHERAL_EVENT** events);
+ void(__cdecl* free_events)(const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int event_count,
+ struct PERIPHERAL_EVENT* events);
+ bool(__cdecl* send_event)(const struct AddonInstance_Peripheral* addonInstance,
+ const struct PERIPHERAL_EVENT* event);
+
+ /// @name Joystick operations
+ ///{
+ PERIPHERAL_ERROR(__cdecl* get_joystick_info)
+ (const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int index,
+ struct JOYSTICK_INFO* info);
+ void(__cdecl* free_joystick_info)(const struct AddonInstance_Peripheral* addonInstance,
+ struct JOYSTICK_INFO* info);
+ PERIPHERAL_ERROR(__cdecl* get_features)
+ (const struct AddonInstance_Peripheral* addonInstance,
+ const struct JOYSTICK_INFO* joystick,
+ const char* controller_id,
+ unsigned int* feature_count,
+ struct JOYSTICK_FEATURE** features);
+ void(__cdecl* free_features)(const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int feature_count,
+ struct JOYSTICK_FEATURE* features);
+ PERIPHERAL_ERROR(__cdecl* map_features)
+ (const struct AddonInstance_Peripheral* addonInstance,
+ const struct JOYSTICK_INFO* joystick,
+ const char* controller_id,
+ unsigned int feature_count,
+ const struct JOYSTICK_FEATURE* features);
+ PERIPHERAL_ERROR(__cdecl* get_ignored_primitives)
+ (const struct AddonInstance_Peripheral* addonInstance,
+ const struct JOYSTICK_INFO* joystick,
+ unsigned int* feature_count,
+ struct JOYSTICK_DRIVER_PRIMITIVE** primitives);
+ void(__cdecl* free_primitives)(const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int,
+ struct JOYSTICK_DRIVER_PRIMITIVE* primitives);
+ PERIPHERAL_ERROR(__cdecl* set_ignored_primitives)
+ (const struct AddonInstance_Peripheral* addonInstance,
+ const struct JOYSTICK_INFO* joystick,
+ unsigned int primitive_count,
+ const struct JOYSTICK_DRIVER_PRIMITIVE* primitives);
+ void(__cdecl* save_button_map)(const struct AddonInstance_Peripheral* addonInstance,
+ const struct JOYSTICK_INFO* joystick);
+ void(__cdecl* revert_button_map)(const struct AddonInstance_Peripheral* addonInstance,
+ const struct JOYSTICK_INFO* joystick);
+ void(__cdecl* reset_button_map)(const struct AddonInstance_Peripheral* addonInstance,
+ const struct JOYSTICK_INFO* joystick,
+ const char* controller_id);
+ void(__cdecl* power_off_joystick)(const struct AddonInstance_Peripheral* addonInstance,
+ unsigned int index);
+ ///}
+ } KodiToAddonFuncTable_Peripheral;
+
+ typedef struct AddonInstance_Peripheral
+ {
+ struct AddonProps_Peripheral* props;
+ struct AddonToKodiFuncTable_Peripheral* toKodi;
+ struct KodiToAddonFuncTable_Peripheral* toAddon;
+ } AddonInstance_Peripheral;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PERIPHERAL_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h
new file mode 100644
index 0000000..96e1eea
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h
@@ -0,0 +1,343 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_H
+#define C_API_ADDONINSTANCE_PVR_H
+
+#include "../../AddonBase.h"
+#include "pvr/pvr_channel_groups.h"
+#include "pvr/pvr_channels.h"
+#include "pvr/pvr_defines.h"
+#include "pvr/pvr_edl.h"
+#include "pvr/pvr_epg.h"
+#include "pvr/pvr_general.h"
+#include "pvr/pvr_menu_hook.h"
+#include "pvr/pvr_providers.h"
+#include "pvr/pvr_recordings.h"
+#include "pvr/pvr_stream.h"
+#include "pvr/pvr_timers.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" main interface function tables between Kodi and addon
+//
+// Values related to all parts and not used direct on addon, are to define here.
+//
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ /*!
+ * @internal
+ * @brief PVR "C" basis API interface
+ *
+ * This field contains things that are exchanged between Kodi and Addon
+ * and is the basis of the PVR-side "C" API.
+ *
+ * @warning Care should be taken when making changes in this fields!\n
+ * Changes can destroy API in addons that have already been created. If a
+ * necessary change or new feature is added, the version of the PVR
+ * at @ref ADDON_INSTANCE_VERSION_PVR_MIN must be increased too.\n
+ * \n
+ * Conditional changes can be made in some places, without min PVR version
+ * increase. The add-on should then use CreateInstanceEx and add partial tests
+ * for this in the C++ header.
+ *
+ * Have by add of new parts a look about **Doxygen** `\\ingroup`, so that
+ * added parts included in documentation.
+ *
+ * If you add addon side related documentation, where his dev need know,
+ * use `///`. For parts only for Kodi make it like here.
+ *
+ * @endinternal
+ */
+
+ struct AddonInstance_PVR;
+
+ /*!
+ * @brief Structure to define typical standard values
+ */
+ typedef struct AddonProperties_PVR
+ {
+ const char* strUserPath;
+ const char* strClientPath;
+ int iEpgMaxFutureDays;
+ int iEpgMaxPastDays;
+ } AddonProperties_PVR;
+
+ /*!
+ * @brief Structure to transfer the methods from Kodi to addon
+ */
+ typedef struct AddonToKodiFuncTable_PVR
+ {
+ // Pointer inside Kodi where used from him to find his class
+ KODI_HANDLE kodiInstance;
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // General callback functions
+ void (*AddMenuHook)(void* kodiInstance, const struct PVR_MENUHOOK* hook);
+ void (*RecordingNotification)(void* kodiInstance,
+ const char* name,
+ const char* fileName,
+ bool on);
+ void (*ConnectionStateChange)(void* kodiInstance,
+ const char* strConnectionString,
+ enum PVR_CONNECTION_STATE newState,
+ const char* strMessage);
+ void (*EpgEventStateChange)(void* kodiInstance,
+ struct EPG_TAG* tag,
+ enum EPG_EVENT_STATE newState);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Transfer functions where give data back to Kodi, e.g. GetChannels calls TransferChannelEntry
+ void (*TransferChannelEntry)(void* kodiInstance,
+ const PVR_HANDLE handle,
+ const struct PVR_CHANNEL* chan);
+ void (*TransferProviderEntry)(void* kodiInstance,
+ const PVR_HANDLE handle,
+ const struct PVR_PROVIDER* chanProvider);
+ void (*TransferChannelGroup)(void* kodiInstance,
+ const PVR_HANDLE handle,
+ const struct PVR_CHANNEL_GROUP* group);
+ void (*TransferChannelGroupMember)(void* kodiInstance,
+ const PVR_HANDLE handle,
+ const struct PVR_CHANNEL_GROUP_MEMBER* member);
+ void (*TransferEpgEntry)(void* kodiInstance,
+ const PVR_HANDLE handle,
+ const struct EPG_TAG* epgentry);
+ void (*TransferRecordingEntry)(void* kodiInstance,
+ const PVR_HANDLE handle,
+ const struct PVR_RECORDING* recording);
+ void (*TransferTimerEntry)(void* kodiInstance,
+ const PVR_HANDLE handle,
+ const struct PVR_TIMER* timer);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Kodi inform interface functions
+ void (*TriggerChannelUpdate)(void* kodiInstance);
+ void (*TriggerProvidersUpdate)(void* kodiInstance);
+ void (*TriggerChannelGroupsUpdate)(void* kodiInstance);
+ void (*TriggerEpgUpdate)(void* kodiInstance, unsigned int iChannelUid);
+ void (*TriggerRecordingUpdate)(void* kodiInstance);
+ void (*TriggerTimerUpdate)(void* kodiInstance);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Stream demux interface functions
+ void (*FreeDemuxPacket)(void* kodiInstance, struct DEMUX_PACKET* pPacket);
+ struct DEMUX_PACKET* (*AllocateDemuxPacket)(void* kodiInstance, int iDataSize);
+ struct PVR_CODEC (*GetCodecByName)(const void* kodiInstance, const char* strCodecName);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // New functions becomes added below and can be on another API change (where
+ // breaks min API version) moved up.
+ } AddonToKodiFuncTable_PVR;
+
+ /*!
+ * @brief Structure to transfer the methods from addon to Kodi
+ */
+ typedef struct KodiToAddonFuncTable_PVR
+ {
+ // Pointer inside addon where used on them to find his instance class (currently unused!)
+ KODI_HANDLE addonInstance;
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // General interface functions
+ enum PVR_ERROR(__cdecl* GetCapabilities)(const struct AddonInstance_PVR*,
+ struct PVR_ADDON_CAPABILITIES*);
+ enum PVR_ERROR(__cdecl* GetBackendName)(const struct AddonInstance_PVR*, char*, int);
+ enum PVR_ERROR(__cdecl* GetBackendVersion)(const struct AddonInstance_PVR*, char*, int);
+ enum PVR_ERROR(__cdecl* GetBackendHostname)(const struct AddonInstance_PVR*, char*, int);
+ enum PVR_ERROR(__cdecl* GetConnectionString)(const struct AddonInstance_PVR*, char*, int);
+ enum PVR_ERROR(__cdecl* GetDriveSpace)(const struct AddonInstance_PVR*, uint64_t*, uint64_t*);
+ enum PVR_ERROR(__cdecl* CallSettingsMenuHook)(const struct AddonInstance_PVR*,
+ const struct PVR_MENUHOOK*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Channel interface functions
+
+ enum PVR_ERROR(__cdecl* GetChannelsAmount)(const struct AddonInstance_PVR*, int*);
+ enum PVR_ERROR(__cdecl* GetChannels)(const struct AddonInstance_PVR*, PVR_HANDLE, bool);
+ enum PVR_ERROR(__cdecl* GetChannelStreamProperties)(const struct AddonInstance_PVR*,
+ const struct PVR_CHANNEL*,
+ struct PVR_NAMED_VALUE*,
+ unsigned int*);
+ enum PVR_ERROR(__cdecl* GetSignalStatus)(const struct AddonInstance_PVR*,
+ int,
+ struct PVR_SIGNAL_STATUS*);
+ enum PVR_ERROR(__cdecl* GetDescrambleInfo)(const struct AddonInstance_PVR*,
+ int,
+ struct PVR_DESCRAMBLE_INFO*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Provider interface functions
+
+ enum PVR_ERROR(__cdecl* GetProvidersAmount)(const struct AddonInstance_PVR*, int*);
+ enum PVR_ERROR(__cdecl* GetProviders)(const struct AddonInstance_PVR*, PVR_HANDLE);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Channel group interface functions
+ enum PVR_ERROR(__cdecl* GetChannelGroupsAmount)(const struct AddonInstance_PVR*, int*);
+ enum PVR_ERROR(__cdecl* GetChannelGroups)(const struct AddonInstance_PVR*, PVR_HANDLE, bool);
+ enum PVR_ERROR(__cdecl* GetChannelGroupMembers)(const struct AddonInstance_PVR*,
+ PVR_HANDLE,
+ const struct PVR_CHANNEL_GROUP*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Channel edit interface functions
+ enum PVR_ERROR(__cdecl* DeleteChannel)(const struct AddonInstance_PVR*,
+ const struct PVR_CHANNEL*);
+ enum PVR_ERROR(__cdecl* RenameChannel)(const struct AddonInstance_PVR*,
+ const struct PVR_CHANNEL*);
+ enum PVR_ERROR(__cdecl* OpenDialogChannelSettings)(const struct AddonInstance_PVR*,
+ const struct PVR_CHANNEL*);
+ enum PVR_ERROR(__cdecl* OpenDialogChannelAdd)(const struct AddonInstance_PVR*,
+ const struct PVR_CHANNEL*);
+ enum PVR_ERROR(__cdecl* OpenDialogChannelScan)(const struct AddonInstance_PVR*);
+ enum PVR_ERROR(__cdecl* CallChannelMenuHook)(const struct AddonInstance_PVR*,
+ const PVR_MENUHOOK*,
+ const PVR_CHANNEL*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // EPG interface functions
+ enum PVR_ERROR(__cdecl* GetEPGForChannel)(
+ const struct AddonInstance_PVR*, PVR_HANDLE, int, time_t, time_t);
+ enum PVR_ERROR(__cdecl* IsEPGTagRecordable)(const struct AddonInstance_PVR*,
+ const struct EPG_TAG*,
+ bool*);
+ enum PVR_ERROR(__cdecl* IsEPGTagPlayable)(const struct AddonInstance_PVR*,
+ const struct EPG_TAG*,
+ bool*);
+ enum PVR_ERROR(__cdecl* GetEPGTagEdl)(const struct AddonInstance_PVR*,
+ const struct EPG_TAG*,
+ struct PVR_EDL_ENTRY[],
+ int*);
+ enum PVR_ERROR(__cdecl* GetEPGTagStreamProperties)(const struct AddonInstance_PVR*,
+ const struct EPG_TAG*,
+ struct PVR_NAMED_VALUE*,
+ unsigned int*);
+ enum PVR_ERROR(__cdecl* SetEPGMaxPastDays)(const struct AddonInstance_PVR*, int);
+ enum PVR_ERROR(__cdecl* SetEPGMaxFutureDays)(const struct AddonInstance_PVR*, int);
+ enum PVR_ERROR(__cdecl* CallEPGMenuHook)(const struct AddonInstance_PVR*,
+ const struct PVR_MENUHOOK*,
+ const struct EPG_TAG*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Recording interface functions
+ enum PVR_ERROR(__cdecl* GetRecordingsAmount)(const struct AddonInstance_PVR*, bool, int*);
+ enum PVR_ERROR(__cdecl* GetRecordings)(const struct AddonInstance_PVR*, PVR_HANDLE, bool);
+ enum PVR_ERROR(__cdecl* DeleteRecording)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*);
+ enum PVR_ERROR(__cdecl* UndeleteRecording)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*);
+ enum PVR_ERROR(__cdecl* DeleteAllRecordingsFromTrash)(const struct AddonInstance_PVR*);
+ enum PVR_ERROR(__cdecl* RenameRecording)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*);
+ enum PVR_ERROR(__cdecl* SetRecordingLifetime)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*);
+ enum PVR_ERROR(__cdecl* SetRecordingPlayCount)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*,
+ int);
+ enum PVR_ERROR(__cdecl* SetRecordingLastPlayedPosition)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*,
+ int);
+ enum PVR_ERROR(__cdecl* GetRecordingLastPlayedPosition)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*,
+ int*);
+ enum PVR_ERROR(__cdecl* GetRecordingEdl)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*,
+ struct PVR_EDL_ENTRY[],
+ int*);
+ enum PVR_ERROR(__cdecl* GetRecordingSize)(const struct AddonInstance_PVR*,
+ const PVR_RECORDING*,
+ int64_t*);
+ enum PVR_ERROR(__cdecl* GetRecordingStreamProperties)(const struct AddonInstance_PVR*,
+ const struct PVR_RECORDING*,
+ struct PVR_NAMED_VALUE*,
+ unsigned int*);
+ enum PVR_ERROR(__cdecl* CallRecordingMenuHook)(const struct AddonInstance_PVR*,
+ const struct PVR_MENUHOOK*,
+ const struct PVR_RECORDING*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Timer interface functions
+ enum PVR_ERROR(__cdecl* GetTimerTypes)(const struct AddonInstance_PVR*,
+ struct PVR_TIMER_TYPE[],
+ int*);
+ enum PVR_ERROR(__cdecl* GetTimersAmount)(const struct AddonInstance_PVR*, int*);
+ enum PVR_ERROR(__cdecl* GetTimers)(const struct AddonInstance_PVR*, PVR_HANDLE);
+ enum PVR_ERROR(__cdecl* AddTimer)(const struct AddonInstance_PVR*, const struct PVR_TIMER*);
+ enum PVR_ERROR(__cdecl* DeleteTimer)(const struct AddonInstance_PVR*,
+ const struct PVR_TIMER*,
+ bool);
+ enum PVR_ERROR(__cdecl* UpdateTimer)(const struct AddonInstance_PVR*, const struct PVR_TIMER*);
+ enum PVR_ERROR(__cdecl* CallTimerMenuHook)(const struct AddonInstance_PVR*,
+ const struct PVR_MENUHOOK*,
+ const struct PVR_TIMER*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Powersaving interface functions
+ enum PVR_ERROR(__cdecl* OnSystemSleep)(const struct AddonInstance_PVR*);
+ enum PVR_ERROR(__cdecl* OnSystemWake)(const struct AddonInstance_PVR*);
+ enum PVR_ERROR(__cdecl* OnPowerSavingActivated)(const struct AddonInstance_PVR*);
+ enum PVR_ERROR(__cdecl* OnPowerSavingDeactivated)(const struct AddonInstance_PVR*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Live stream read interface functions
+ bool(__cdecl* OpenLiveStream)(const struct AddonInstance_PVR*, const struct PVR_CHANNEL*);
+ void(__cdecl* CloseLiveStream)(const struct AddonInstance_PVR*);
+ int(__cdecl* ReadLiveStream)(const struct AddonInstance_PVR*, unsigned char*, unsigned int);
+ int64_t(__cdecl* SeekLiveStream)(const struct AddonInstance_PVR*, int64_t, int);
+ int64_t(__cdecl* LengthLiveStream)(const struct AddonInstance_PVR*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Recording stream read interface functions
+ bool(__cdecl* OpenRecordedStream)(const struct AddonInstance_PVR*, const struct PVR_RECORDING*);
+ void(__cdecl* CloseRecordedStream)(const struct AddonInstance_PVR*);
+ int(__cdecl* ReadRecordedStream)(const struct AddonInstance_PVR*, unsigned char*, unsigned int);
+ int64_t(__cdecl* SeekRecordedStream)(const struct AddonInstance_PVR*, int64_t, int);
+ int64_t(__cdecl* LengthRecordedStream)(const struct AddonInstance_PVR*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // Stream demux interface functions
+ enum PVR_ERROR(__cdecl* GetStreamProperties)(const struct AddonInstance_PVR*,
+ struct PVR_STREAM_PROPERTIES*);
+ struct DEMUX_PACKET*(__cdecl* DemuxRead)(const struct AddonInstance_PVR*);
+ void(__cdecl* DemuxReset)(const struct AddonInstance_PVR*);
+ void(__cdecl* DemuxAbort)(const struct AddonInstance_PVR*);
+ void(__cdecl* DemuxFlush)(const struct AddonInstance_PVR*);
+ void(__cdecl* SetSpeed)(const struct AddonInstance_PVR*, int);
+ void(__cdecl* FillBuffer)(const struct AddonInstance_PVR*, bool);
+ bool(__cdecl* SeekTime)(const struct AddonInstance_PVR*, double, bool, double*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // General stream interface functions
+ bool(__cdecl* CanPauseStream)(const struct AddonInstance_PVR*);
+ void(__cdecl* PauseStream)(const struct AddonInstance_PVR*, bool);
+ bool(__cdecl* CanSeekStream)(const struct AddonInstance_PVR*);
+ bool(__cdecl* IsRealTimeStream)(const struct AddonInstance_PVR*);
+ enum PVR_ERROR(__cdecl* GetStreamTimes)(const struct AddonInstance_PVR*,
+ struct PVR_STREAM_TIMES*);
+ enum PVR_ERROR(__cdecl* GetStreamReadChunkSize)(const struct AddonInstance_PVR*, int*);
+
+ //--==----==----==----==----==----==----==----==----==----==----==----==----==
+ // New functions becomes added below and can be on another API change (where
+ // breaks min API version) moved up.
+ } KodiToAddonFuncTable_PVR;
+
+ typedef struct AddonInstance_PVR
+ {
+ struct AddonProperties_PVR* props;
+ struct AddonToKodiFuncTable_PVR* toKodi;
+ struct KodiToAddonFuncTable_PVR* toAddon;
+ } AddonInstance_PVR;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/CMakeLists.txt
new file mode 100644
index 0000000..c5ade1c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ pvr_channel_groups.h
+ pvr_channels.h
+ pvr_defines.h
+ pvr_edl.h
+ pvr_epg.h
+ pvr_general.h
+ pvr_menu_hook.h
+ pvr_providers.h
+ pvr_recordings.h
+ pvr_stream.h
+ pvr_timers.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_addon-instance_pvr)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channel_groups.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channel_groups.h
new file mode 100644
index 0000000..f8213fb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channel_groups.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_CHANNEL_GROUPS_H
+#define C_API_ADDONINSTANCE_PVR_CHANNEL_GROUPS_H
+
+#include "pvr_defines.h"
+
+#include <stdbool.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 3 - PVR channel group
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ /*!
+ * @brief "C" PVR add-on channel group.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRChannelGroup for description of values.
+ */
+ typedef struct PVR_CHANNEL_GROUP
+ {
+ char strGroupName[PVR_ADDON_NAME_STRING_LENGTH];
+ bool bIsRadio;
+ unsigned int iPosition;
+ } PVR_CHANNEL_GROUP;
+
+ /*!
+ * @brief "C" PVR add-on channel group member.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRChannelGroupMember for description of values.
+ */
+ typedef struct PVR_CHANNEL_GROUP_MEMBER
+ {
+ char strGroupName[PVR_ADDON_NAME_STRING_LENGTH];
+ unsigned int iChannelUniqueId;
+ unsigned int iChannelNumber;
+ unsigned int iSubChannelNumber;
+ int iOrder;
+ } PVR_CHANNEL_GROUP_MEMBER;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_CHANNEL_GROUPS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channels.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channels.h
new file mode 100644
index 0000000..134384f
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channels.h
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_CHANNELS_H
+#define C_API_ADDONINSTANCE_PVR_CHANNELS_H
+
+#include "pvr_defines.h"
+
+#include <stdbool.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 2 - PVR channel
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Channel
+ /// @brief Denotes that no channel uid is available.
+ ///
+ /// Special @ref kodi::addon::PVRTimer::SetClientChannelUid() and
+ /// @ref kodi::addon::PVRRecording::SetChannelUid() value to indicate that no
+ /// channel uid is available.
+ #define PVR_CHANNEL_INVALID_UID -1
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on channel.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRChannel for description of values.
+ */
+ typedef struct PVR_CHANNEL
+ {
+ unsigned int iUniqueId;
+ bool bIsRadio;
+ unsigned int iChannelNumber;
+ unsigned int iSubChannelNumber;
+ char strChannelName[PVR_ADDON_NAME_STRING_LENGTH];
+ char strMimeType[PVR_ADDON_INPUT_FORMAT_STRING_LENGTH];
+ unsigned int iEncryptionSystem;
+ char strIconPath[PVR_ADDON_URL_STRING_LENGTH];
+ bool bIsHidden;
+ bool bHasArchive;
+ int iOrder;
+ int iClientProviderUid;
+ } PVR_CHANNEL;
+
+ /*!
+ * @brief "C" PVR add-on signal status information.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRSignalStatus for description of values.
+ */
+ typedef struct PVR_SIGNAL_STATUS
+ {
+ char strAdapterName[PVR_ADDON_NAME_STRING_LENGTH];
+ char strAdapterStatus[PVR_ADDON_NAME_STRING_LENGTH];
+ char strServiceName[PVR_ADDON_NAME_STRING_LENGTH];
+ char strProviderName[PVR_ADDON_NAME_STRING_LENGTH];
+ char strMuxName[PVR_ADDON_NAME_STRING_LENGTH];
+ int iSNR;
+ int iSignal;
+ long iBER;
+ long iUNC;
+ } PVR_SIGNAL_STATUS;
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo
+ /// @brief Special @ref cpp_kodi_addon_pvr_Defs_Channel_PVRDescrambleInfo
+ /// value to indicate that a struct member's value is not available
+ ///
+ #define PVR_DESCRAMBLE_INFO_NOT_AVAILABLE -1
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on descramble information.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRDescrambleInfo for description of values.
+ */
+ typedef struct PVR_DESCRAMBLE_INFO
+ {
+ int iPid;
+ int iCaid;
+ int iProvid;
+ int iEcmTime;
+ int iHops;
+ char strCardSystem[PVR_ADDON_DESCRAMBLE_INFO_STRING_LENGTH];
+ char strReader[PVR_ADDON_DESCRAMBLE_INFO_STRING_LENGTH];
+ char strFrom[PVR_ADDON_DESCRAMBLE_INFO_STRING_LENGTH];
+ char strProtocol[PVR_ADDON_DESCRAMBLE_INFO_STRING_LENGTH];
+ } PVR_DESCRAMBLE_INFO;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_CHANNELS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_defines.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_defines.h
new file mode 100644
index 0000000..5bd24dc
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_defines.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_DEFINES_H
+#define C_API_ADDONINSTANCE_PVR_DEFINES_H
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Standard PVR definitions
+//
+// Values related to all parts and not used direct on addon, are to define here.
+//
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ /*!
+ * @brief API array sizes which are used for data exchange between
+ * Kodi and addon.
+ */
+ ///@{
+ #define PVR_ADDON_NAME_STRING_LENGTH 1024
+ #define PVR_ADDON_URL_STRING_LENGTH 1024
+ #define PVR_ADDON_DESC_STRING_LENGTH 1024
+ #define PVR_ADDON_INPUT_FORMAT_STRING_LENGTH 32
+ #define PVR_ADDON_EDL_LENGTH 64
+ #define PVR_ADDON_TIMERTYPE_ARRAY_SIZE 32
+ #define PVR_ADDON_TIMERTYPE_VALUES_ARRAY_SIZE 512
+ #define PVR_ADDON_TIMERTYPE_VALUES_ARRAY_SIZE_SMALL 128
+ #define PVR_ADDON_TIMERTYPE_STRING_LENGTH 128
+ #define PVR_ADDON_ATTRIBUTE_DESC_LENGTH 128
+ #define PVR_ADDON_ATTRIBUTE_VALUES_ARRAY_SIZE 512
+ #define PVR_ADDON_DESCRAMBLE_INFO_STRING_LENGTH 64
+ #define PVR_ADDON_DATE_STRING_LENGTH 32
+ #define PVR_ADDON_COUNTRIES_STRING_LENGTH 128
+ #define PVR_ADDON_LANGUAGES_STRING_LENGTH 128
+ ///@}
+
+ /*!
+ * @brief "C" Representation of a general attribute integer value.
+ */
+ typedef struct PVR_ATTRIBUTE_INT_VALUE
+ {
+ int iValue;
+ char strDescription[PVR_ADDON_ATTRIBUTE_DESC_LENGTH];
+ } PVR_ATTRIBUTE_INT_VALUE;
+
+ /*!
+ * @brief "C" Representation of a named value.
+ */
+ typedef struct PVR_NAMED_VALUE
+ {
+ char strName[PVR_ADDON_NAME_STRING_LENGTH];
+ char strValue[PVR_ADDON_NAME_STRING_LENGTH];
+ } PVR_NAMED_VALUE;
+
+ /*!
+ * @brief Handle used to return data from the PVR add-on to CPVRClient
+ */
+ struct PVR_HANDLE_STRUCT
+ {
+ void* callerAddress; /*!< address of the caller */
+ void* dataAddress; /*!< address to store data in */
+ int dataIdentifier; /*!< parameter to pass back when calling the callback */
+ };
+ typedef struct PVR_HANDLE_STRUCT* PVR_HANDLE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_DEFINES_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_edl.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_edl.h
new file mode 100644
index 0000000..c74a113
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_edl.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_EDL_H
+#define C_API_ADDONINSTANCE_PVR_EDL_H
+
+#include "pvr_defines.h"
+
+#include <stdint.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 8 - PVR Edit definition list (EDL)
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_EDLEntry_PVR_EDL_TYPE enum PVR_EDL_TYPE
+ /// @ingroup cpp_kodi_addon_pvr_Defs_EDLEntry
+ /// @brief **Edit definition list types**\n
+ /// Possible type values for @ref cpp_kodi_addon_pvr_Defs_EDLEntry_PVREDLEntry.
+ ///
+ ///@{
+ typedef enum PVR_EDL_TYPE
+ {
+ /// @brief __0__ : cut (completely remove content)
+ PVR_EDL_TYPE_CUT = 0,
+
+ /// @brief __1__ : mute audio
+ PVR_EDL_TYPE_MUTE = 1,
+
+ /// @brief __2__ : scene markers (chapter seeking)
+ PVR_EDL_TYPE_SCENE = 2,
+
+ /// @brief __3__ : commercial breaks
+ PVR_EDL_TYPE_COMBREAK = 3
+ } PVR_EDL_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" Edit definition list entry.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVREDLEntry for description of values.
+ */
+ typedef struct PVR_EDL_ENTRY
+ {
+ int64_t start;
+ int64_t end;
+ enum PVR_EDL_TYPE type;
+ } PVR_EDL_ENTRY;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_EDL_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_epg.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_epg.h
new file mode 100644
index 0000000..9128b0d
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_epg.h
@@ -0,0 +1,657 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_EPG_H
+#define C_API_ADDONINSTANCE_PVR_EPG_H
+
+#include "pvr_defines.h"
+
+#include <time.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 4 - PVR EPG
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT enum EPG_EVENT_CONTENTMASK (and sub types)
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg
+ /// @brief **EPG entry content event types.**\n
+ /// These ID's come from the DVB-SI EIT table "content descriptor"
+ /// Also known under the name "E-book genre assignments".
+ ///
+ /// See [ETSI EN 300 468 V1.14.1 (2014-05)](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf)
+ /// about.
+ ///
+ /// Values used by this functions:
+ /// - @ref kodi::addon::PVREPGTag::SetGenreType()
+ /// - @ref kodi::addon::PVREPGTag::SetGenreSubType()
+ /// - @ref kodi::addon::PVRRecording::SetGenreType()
+ /// - @ref kodi::addon::PVRRecording::SetGenreSubType()
+ ///
+ /// Following types are listed here:
+ /// | emum Type | Description
+ /// |-----------|--------------------
+ /// | @ref EPG_EVENT_CONTENTMASK | EPG entry main content to use.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_MOVIEDRAMA event types for sub type of <b>"Movie/Drama"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS event types for sub type of <b>"News/Current affairs"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_SHOW | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SHOW event types for sub type of <b>"Show/Game show"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_SPORTS | @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SPORTS event types for sub type of <b>"Sports"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_CHILDRENYOUTH event types for sub type of <b>"Children's/Youth programmes"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE event types for sub type of <b>"Music/Ballet/Dance"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_ARTSCULTURE event types for sub type of <b>"Arts/Culture (without music)"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS event types for sub type of <b>"Social/Political issues/Economics"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE event types for sub type of <b>"Education/Science/Factual topics"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_LEISUREHOBBIES event types for sub type of <b>"Leisure hobbies"</b>.
+ /// | @ref EPG_EVENT_CONTENTSUBMASK_SPECIAL | EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SPECIAL event types for sub type of <b>"Special characteristics"</b>.
+ ///@{
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry main content to use.
+ ///
+ ///@{
+ typedef enum EPG_EVENT_CONTENTMASK
+ {
+ /// @brief __0x00__ : Undefined content mask entry.
+ EPG_EVENT_CONTENTMASK_UNDEFINED = 0x00,
+
+ /// @brief __0x10__ : Movie/Drama.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA about related sub types.
+ EPG_EVENT_CONTENTMASK_MOVIEDRAMA = 0x10,
+
+ /// @brief __0x20__ : News/Current affairs.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS about related sub types.
+ EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS = 0x20,
+
+ /// @brief __0x30__ : Show/Game show.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_SHOW about related sub types.
+ EPG_EVENT_CONTENTMASK_SHOW = 0x30,
+
+ /// @brief __0x40__ : Sports.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_SPORTS about related sub types.
+ EPG_EVENT_CONTENTMASK_SPORTS = 0x40,
+
+ /// @brief __0x50__ : Children's/Youth programmes.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH about related sub types.
+ EPG_EVENT_CONTENTMASK_CHILDRENYOUTH = 0x50,
+
+ /// @brief __0x60__ : Music/Ballet/Dance.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE about related sub types.
+ EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE = 0x60,
+
+ /// @brief __0x70__ : Arts/Culture (without music).\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE about related sub types.
+ EPG_EVENT_CONTENTMASK_ARTSCULTURE = 0x70,
+
+ /// @brief __0x80__ : Social/Political issues/Economics.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS about related sub types.
+ EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS = 0x80,
+
+ /// @brief __0x90__ : Education/Science/Factual topics.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE about related sub types.
+ EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE = 0x90,
+
+ /// @brief __0xA0__ : Leisure hobbies.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES about related sub types.
+ EPG_EVENT_CONTENTMASK_LEISUREHOBBIES = 0xA0,
+
+ /// @brief __0xB0__ : Special characteristics.\n
+ /// \n
+ /// See @ref EPG_EVENT_CONTENTSUBMASK_SPECIAL about related sub types.
+ EPG_EVENT_CONTENTMASK_SPECIAL = 0xB0,
+
+ /// @brief __0xF0__ User defined.
+ EPG_EVENT_CONTENTMASK_USERDEFINED = 0xF0,
+
+ /// @brief Used to override standard genre types with a own name about.\n
+ /// \n
+ /// Set to this value @ref EPG_GENRE_USE_STRING on following places:
+ /// - @ref kodi::addon::PVREPGTag::SetGenreType()
+ /// - @ref kodi::addon::PVREPGTag::SetGenreSubType()
+ /// - @ref kodi::addon::PVRRecording::SetGenreType()
+ /// - @ref kodi::addon::PVRRecording::SetGenreSubType()
+ ///
+ /// @warning Value here is not a [ETSI EN 300 468 V1.14.1 (2014-05)](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf)
+ /// conform.
+ ///
+ /// @note This is a own Kodi definition to set that genre is given by own
+ /// string. Used on @ref kodi::addon::PVREPGTag::SetGenreDescription() and
+ /// @ref kodi::addon::PVRRecording::SetGenreDescription()
+ EPG_GENRE_USE_STRING = 0x100
+ } EPG_EVENT_CONTENTMASK;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_MOVIEDRAMA event
+ /// types for sub type of <b>"Movie/Drama"</b>.
+ ///
+ ///@{
+ typedef enum EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA
+ {
+ /// @brief __0x0__ : Movie/drama (general).
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Detective/thriller.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_DETECTIVE_THRILLER = 0x1,
+
+ /// @brief __0x2__ : Adventure/western/war.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_ADVENTURE_WESTERN_WAR = 0x2,
+
+ /// @brief __0x3__ : Science fiction/fantasy/horror.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_SCIENCEFICTION_FANTASY_HORROR = 0x3,
+
+ /// @brief __0x4__ : Comedy.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_COMEDY = 0x4,
+
+ /// @brief __0x5__ : Soap/melodrama/folkloric.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_SOAP_MELODRAMA_FOLKLORIC = 0x5,
+
+ /// @brief __0x6__ : Romance.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_ROMANCE = 0x6,
+
+ /// @brief __0x7__ : Serious/classical/religious/historical movie/drama.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_SERIOUS_CLASSICAL_RELIGIOUS_HISTORICAL = 0x7,
+
+ /// @brief __0x8__ : Adult movie/drama.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_ADULT = 0x8,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_MOVIEDRAMA;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS event
+ /// types for sub type of <b>"News/Current affairs"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS
+ {
+ /// @brief __0x0__ : News/current affairs (general).
+ EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS_GENERAL = 0x0,
+
+ /// @brief __0x1__ : News/weather report.
+ EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS_WEATHER = 0x1,
+
+ /// @brief __0x2__ : News magazine.
+ EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS_MAGAZINE = 0x2,
+
+ /// @brief __0x3__ : Documentary.
+ EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS_DOCUMENTARY = 0x3,
+
+ /// @brief __0x4__ : Discussion/interview/debate
+ EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS_DISCUSSION_INTERVIEW_DEBATE = 0x4,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_NEWSCURRENTAFFAIRS;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SHOW event
+ /// types for sub type of <b>"Show/Game show"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_SHOW
+ {
+ /// @brief __0x0__ : Show/game show (general).
+ EPG_EVENT_CONTENTSUBMASK_SHOW_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Game show/quiz/contest.
+ EPG_EVENT_CONTENTSUBMASK_SHOW_GAMESHOW_QUIZ_CONTEST = 0x1,
+
+ /// @brief __0x2__ : Variety show.
+ EPG_EVENT_CONTENTSUBMASK_SHOW_VARIETY_SHOW = 0x2,
+
+ /// @brief __0x3__ : Talk show.
+ EPG_EVENT_CONTENTSUBMASK_SHOW_TALK_SHOW = 0x3,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_SHOW_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_SHOW;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SPORTS event
+ /// types for sub type of <b>"Sports"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_SPORTS
+ {
+ /// @brief __0x0__ : Sports (general).
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Special events (Olympic Games, World Cup, etc.).
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_OLYMPICGAMES_WORLDCUP = 0x1,
+
+ /// @brief __0x2__ : Sports magazines.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_SPORTS_MAGAZINES = 0x2,
+
+ /// @brief __0x3__ : Football/soccer.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_FOOTBALL_SOCCER = 0x3,
+
+ /// @brief __0x4__ : Tennis/squash.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_TENNIS_SQUASH = 0x4,
+
+ /// @brief __0x5__ : Team sports (excluding football).
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_TEAMSPORTS = 0x5,
+
+ /// @brief __0x6__ : Athletics.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_ATHLETICS = 0x6,
+
+ /// @brief __0x7__ : Motor sport.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_MOTORSPORT = 0x7,
+
+ /// @brief __0x8__ : Water sport.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_WATERSPORT = 0x8,
+
+ /// @brief __0x9__ : Winter sports.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_WINTERSPORTS = 0x9,
+
+ /// @brief __0xA__ : Equestrian.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_EQUESTRIAN = 0xA,
+
+ /// @brief __0xB__ : Martial sports.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_MARTIALSPORTS = 0xB,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_SPORTS_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_SPORTS;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_CHILDRENYOUTH event
+ /// types for sub type of <b>"Children's/Youth programmes"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH
+ {
+ /// @brief __0x0__ : Children's/youth programmes (general).
+ EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Pre-school children's programmes.
+ EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH_PRESCHOOL_CHILDREN = 0x1,
+
+ /// @brief __0x2__ : Entertainment programmes for 6 to 14.
+ EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH_ENTERTAIN_6TO14 = 0x2,
+
+ /// @brief __0x3__ : Entertainment programmes for 10 to 16.
+ EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH_ENTERTAIN_10TO16 = 0x3,
+
+ /// @brief __0x4__ : Informational/educational/school programmes.
+ EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH_INFORMATIONAL_EDUCATIONAL_SCHOOL = 0x4,
+
+ /// @brief __0x5__ : Cartoons/puppets.
+ EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH_CARTOONS_PUPPETS = 0x5,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_CHILDRENYOUTH;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE event
+ /// types for sub type of <b>"Music/Ballet/Dance"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE
+ {
+ /// @brief __0x0__ : Music/ballet/dance (general).
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Rock/pop.
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_ROCKPOP = 0x1,
+
+ /// @brief __0x2__ : Serious music/classical music.
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_SERIOUSMUSIC_CLASSICALMUSIC = 0x2,
+
+ /// @brief __0x3__ : Folk/traditional music.
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_FOLK_TRADITIONAL_MUSIC = 0x3,
+
+ /// @brief __0x4__ : Jazz.
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_JAZZ = 0x4,
+
+ /// @brief __0x5__ : Musical/opera.
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_MUSICAL_OPERA = 0x5,
+
+ /// @brief __0x6__ : Ballet.
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_BALLET = 0x6,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_MUSICBALLETDANCE;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_ARTSCULTURE event
+ /// types for sub type of <b>"Arts/Culture (without music)"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE
+ {
+ /// @brief __0x0__ : Arts/culture (without music, general).
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Performing arts.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_PERFORMINGARTS = 0x1,
+
+ /// @brief __0x2__ : Fine arts.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_FINEARTS = 0x2,
+
+ /// @brief __0x3__ : Religion.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_RELIGION = 0x3,
+
+ /// @brief __0x4__ : Popular culture/traditional arts.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_POPULARCULTURE_TRADITIONALARTS = 0x4,
+
+ /// @brief __0x5__ : Literature.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_LITERATURE = 0x5,
+
+ /// @brief __0x6__ : Film/cinema.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_FILM_CINEMA = 0x6,
+
+ /// @brief __0x7__ : Experimental film/video.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_EXPERIMENTALFILM_VIDEO = 0x7,
+
+ /// @brief __0x8__ : Broadcasting/press.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_BROADCASTING_PRESS = 0x8,
+
+ /// @brief __0x9__ : New media.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_NEWMEDIA = 0x9,
+
+ /// @brief __0xA__ : Arts/culture magazines.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_ARTS_CULTUREMAGAZINES = 0xA,
+
+ /// @brief __0xB__ : Fashion.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_FASHION = 0xB,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_ARTSCULTURE;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS event
+ /// types for sub type of <b>"Social/Political issues/Economics"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS
+ {
+ /// @brief __0x0__ : Social/political issues/economics (general).
+ EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Magazines/reports/documentary.
+ EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS_MAGAZINES_REPORTS_DOCUMENTARY = 0x1,
+
+ /// @brief __0x2__ : Economics/social advisory.
+ EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS_ECONOMICS_SOCIALADVISORY = 0x2,
+
+ /// @brief __0x3__ : Remarkable people.
+ EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS_REMARKABLEPEOPLE = 0x3,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_SOCIALPOLITICALECONOMICS;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE event
+ /// types for sub type of <b>"Education/Science/Factual topics"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE
+ {
+ /// @brief __0x0__ : Education/science/factual topics (general).
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Nature/animals/environment.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_NATURE_ANIMALS_ENVIRONMENT = 0x1,
+
+ /// @brief __0x2__ : Technology/natural sciences.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_TECHNOLOGY_NATURALSCIENCES = 0x2,
+
+ /// @brief __0x3__ : Medicine/physiology/psychology.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_MEDICINE_PHYSIOLOGY_PSYCHOLOGY = 0x3,
+
+ /// @brief __0x4__ : Foreign countries/expeditions.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_FOREIGNCOUNTRIES_EXPEDITIONS = 0x4,
+
+ /// @brief __0x5__ : Social/spiritual sciences.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_SOCIAL_SPIRITUALSCIENCES = 0x5,
+
+ /// @brief __0x6__ : Further education.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_FURTHEREDUCATION = 0x6,
+
+ /// @brief __0x7__ : Languages.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_LANGUAGES = 0x7,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_EDUCATIONALSCIENCE;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_LEISUREHOBBIES event
+ /// types for sub type of <b>"Leisure hobbies"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES
+ {
+ /// @brief __0x0__ : Leisure hobbies (general) .
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Tourism/travel.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_TOURISM_TRAVEL = 0x1,
+
+ /// @brief __0x2__ : Handicraft.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_HANDICRAFT = 0x2,
+
+ /// @brief __0x3__ : Motoring.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_MOTORING = 0x3,
+
+ /// @brief __0x4__ : Fitness and health.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_FITNESSANDHEALTH = 0x4,
+
+ /// @brief __0x5__ : Cooking.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_COOKING = 0x5,
+
+ /// @brief __0x6__ : Advertisement/shopping.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_ADVERTISEMENT_SHOPPING = 0x6,
+
+ /// @brief __0x7__ : Gardening.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_GARDENING = 0x7,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_LEISUREHOBBIES;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT
+ /// @brief EPG entry sub content to @ref EPG_EVENT_CONTENTMASK_SPECIAL event
+ /// types for sub type of <b>"Special characteristics"</b>.
+ ///
+ typedef enum EPG_EVENT_CONTENTSUBMASK_SPECIAL
+ {
+ /// @brief __0x0__ : Special characteristics / Original language (general).
+ EPG_EVENT_CONTENTSUBMASK_SPECIAL_GENERAL = 0x0,
+
+ /// @brief __0x1__ : Black and white.
+ EPG_EVENT_CONTENTSUBMASK_SPECIAL_BLACKANDWHITE = 0x1,
+
+ /// @brief __0x2__ : Unpublished.
+ EPG_EVENT_CONTENTSUBMASK_SPECIAL_UNPUBLISHED = 0x2,
+
+ /// @brief __0x3__ : Live broadcast.
+ EPG_EVENT_CONTENTSUBMASK_SPECIAL_LIVEBROADCAST = 0x3,
+
+ /// @brief __0x4__ : Plano-stereoscopic.
+ EPG_EVENT_CONTENTSUBMASK_SPECIAL_PLANOSTEREOSCOPIC = 0x4,
+
+ /// @brief __0x5__ : Local or regional.
+ EPG_EVENT_CONTENTSUBMASK_SPECIAL_LOCALORREGIONAL = 0x5,
+
+ /// @brief __0xF__ : User defined.
+ EPG_EVENT_CONTENTSUBMASK_SPECIAL_USERDEFINED = 0xF
+ } EPG_EVENT_CONTENTSUBMASK_SPECIAL;
+ //----------------------------------------------------------------------------
+
+ ///@}
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg
+ /// @brief Separator to use in strings containing different tokens, for example
+ /// writers, directors, actors of an event.
+ ///
+ #define EPG_STRING_TOKEN_SEPARATOR ","
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_epg_EPG_TAG_FLAG enum EPG_TAG_FLAG
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg
+ /// @brief <b>Bit field of independent flags associated with the EPG entry.</b>\n
+ /// Values used by @ref kodi::addon::PVREPGTag::SetFlags().
+ ///
+ /// Here's example about the use of this:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVREPGTag tag;
+ /// tag.SetFlags(EPG_TAG_FLAG_IS_SERIES | EPG_TAG_FLAG_IS_NEW);
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ typedef enum EPG_TAG_FLAG
+ {
+ /// @brief __0000 0000__ : Nothing special to say about this entry.
+ EPG_TAG_FLAG_UNDEFINED = 0,
+
+ /// @brief __0000 0001__ : This EPG entry is part of a series.
+ EPG_TAG_FLAG_IS_SERIES = (1 << 0),
+
+ /// @brief __0000 0010__ : This EPG entry will be flagged as new.
+ EPG_TAG_FLAG_IS_NEW = (1 << 1),
+
+ /// @brief __0000 0100__ : This EPG entry will be flagged as a premiere.
+ EPG_TAG_FLAG_IS_PREMIERE = (1 << 2),
+
+ /// @brief __0000 1000__ : This EPG entry will be flagged as a finale.
+ EPG_TAG_FLAG_IS_FINALE = (1 << 3),
+
+ /// @brief __0001 0000__ : This EPG entry will be flagged as live.
+ EPG_TAG_FLAG_IS_LIVE = (1 << 4),
+ } EPG_TAG_FLAG;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg
+ /// @brief Special PVREPGTag::SetUniqueBroadcastId value
+ ///
+ /// Special @ref kodi::addon::PVREPGTag::SetUniqueBroadcastId() value to
+ /// indicate that a tag has not a valid EPG event uid.
+ ///
+ #define EPG_TAG_INVALID_UID 0
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg
+ /// @brief Special @ref kodi::addon::PVREPGTag::SetSeriesNumber(), @ref kodi::addon::PVREPGTag::SetEpisodeNumber()
+ /// and @ref kodi::addon::PVREPGTag::SetEpisodePartNumber() value to indicate
+ /// it is not to be used.
+ ///
+ #define EPG_TAG_INVALID_SERIES_EPISODE -1
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg
+ /// @brief Timeframe value for use with @ref kodi::addon::CInstancePVRClient::SetEPGTimeFrame()
+ /// function to indicate "no timeframe".
+ ///
+ #define EPG_TIMEFRAME_UNLIMITED -1
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_epg_EPG_EVENT_STATE enum EPG_EVENT_STATE
+ /// @ingroup cpp_kodi_addon_pvr_Defs_epg
+ /// @brief **EPG event states.**\n
+ /// Used with @ref kodi::addon::CInstancePVRClient::EpgEventStateChange()
+ /// callback.
+ ///
+ ///@{
+ typedef enum EPG_EVENT_STATE
+ {
+ /// @brief __0__ : Event created.
+ EPG_EVENT_CREATED = 0,
+
+ /// @brief __1__ : Event updated.
+ EPG_EVENT_UPDATED = 1,
+
+ /// @brief __2__ : Event deleted.
+ EPG_EVENT_DELETED = 2,
+ } EPG_EVENT_STATE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on channel group member.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVREPGTag for description of values.
+ */
+ typedef struct EPG_TAG
+ {
+ unsigned int iUniqueBroadcastId;
+ unsigned int iUniqueChannelId;
+ const char* strTitle;
+ time_t startTime;
+ time_t endTime;
+ const char* strPlotOutline;
+ const char* strPlot;
+ const char* strOriginalTitle;
+ const char* strCast;
+ const char* strDirector;
+ const char* strWriter;
+ int iYear;
+ const char* strIMDBNumber;
+ const char* strIconPath;
+ int iGenreType;
+ int iGenreSubType;
+ const char* strGenreDescription;
+ const char* strFirstAired;
+ int iParentalRating;
+ const char* strParentalRatingCode;
+ int iStarRating;
+ int iSeriesNumber;
+ int iEpisodeNumber;
+ int iEpisodePartNumber;
+ const char* strEpisodeName;
+ unsigned int iFlags;
+ const char* strSeriesLink;
+ } EPG_TAG;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_EPG_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_general.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_general.h
new file mode 100644
index 0000000..32413cb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_general.h
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_GENERAL_H
+#define C_API_ADDONINSTANCE_PVR_GENERAL_H
+
+#include "../inputstream/stream_constants.h"
+#include "pvr_defines.h"
+
+#include <stdbool.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 1 - General PVR
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_General_PVR_ERROR enum PVR_ERROR
+ /// @ingroup cpp_kodi_addon_pvr_Defs_General
+ /// @brief **PVR add-on error codes**\n
+ /// Used as return values on most PVR related functions.
+ ///
+ /// In this way, a PVR instance signals errors in its processing and, under
+ /// certain conditions, allows Kodi to make corrections.
+ ///
+ ///@{
+ typedef enum PVR_ERROR
+ {
+ /// @brief __0__ : No error occurred.
+ PVR_ERROR_NO_ERROR = 0,
+
+ /// @brief __-1__ : An unknown error occurred.
+ PVR_ERROR_UNKNOWN = -1,
+
+ /// @brief __-2__ : The method that Kodi called is not implemented by the add-on.
+ PVR_ERROR_NOT_IMPLEMENTED = -2,
+
+ /// @brief __-3__ : The backend reported an error, or the add-on isn't connected.
+ PVR_ERROR_SERVER_ERROR = -3,
+
+ /// @brief __-4__ : The command was sent to the backend, but the response timed out.
+ PVR_ERROR_SERVER_TIMEOUT = -4,
+
+ /// @brief __-5__ : The command was rejected by the backend.
+ PVR_ERROR_REJECTED = -5,
+
+ /// @brief __-6__ : The requested item can not be added, because it's already present.
+ PVR_ERROR_ALREADY_PRESENT = -6,
+
+ /// @brief __-7__ : The parameters of the method that was called are invalid for this
+ /// operation.
+ PVR_ERROR_INVALID_PARAMETERS = -7,
+
+ /// @brief __-8__ : A recording is running, so the timer can't be deleted without
+ /// doing a forced delete.
+ PVR_ERROR_RECORDING_RUNNING = -8,
+
+ /// @brief __-9__ : The command failed.
+ PVR_ERROR_FAILED = -9,
+ } PVR_ERROR;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_General_PVR_CONNECTION_STATE enum PVR_CONNECTION_STATE
+ /// @ingroup cpp_kodi_addon_pvr_Defs_General
+ /// @brief **PVR backend connection states**\n
+ /// Used with @ref kodi::addon::CInstancePVRClient::ConnectionStateChange() callback.
+ ///
+ /// With this, a PVR instance signals that Kodi should perform special
+ /// operations.
+ ///
+ ///@{
+ typedef enum PVR_CONNECTION_STATE
+ {
+ /// @brief __0__ : Unknown state (e.g. not yet tried to connect).
+ PVR_CONNECTION_STATE_UNKNOWN = 0,
+
+ /// @brief __1__ : Backend server is not reachable (e.g. server not existing or
+ /// network down).
+ PVR_CONNECTION_STATE_SERVER_UNREACHABLE = 1,
+
+ /// @brief __2__ : Backend server is reachable, but there is not the expected type of
+ /// server running (e.g. HTSP required, but FTP running at given server:port).
+ PVR_CONNECTION_STATE_SERVER_MISMATCH = 2,
+
+ /// @brief __3__ : Backend server is reachable, but server version does not match
+ /// client requirements.
+ PVR_CONNECTION_STATE_VERSION_MISMATCH = 3,
+
+ /// @brief __4__ : Backend server is reachable, but denies client access (e.g. due
+ /// to wrong credentials).
+ PVR_CONNECTION_STATE_ACCESS_DENIED = 4,
+
+ /// @brief __5__ : Connection to backend server is established.
+ PVR_CONNECTION_STATE_CONNECTED = 5,
+
+ /// @brief __6__ : No connection to backend server (e.g. due to network errors or
+ /// client initiated disconnect).
+ PVR_CONNECTION_STATE_DISCONNECTED = 6,
+
+ /// @brief __7__ : Connecting to backend.
+ PVR_CONNECTION_STATE_CONNECTING = 7,
+ } PVR_CONNECTION_STATE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_General_PVR_STREAM_PROPERTY definition PVR_STREAM_PROPERTY
+ /// @ingroup cpp_kodi_addon_pvr_Defs_General_Inputstream
+ /// @brief **PVR related stream property values**\n
+ /// This is used to pass additional data to Kodi on a given PVR stream.
+ ///
+ /// Then transferred to livestream, recordings or EPG Tag stream using the
+ /// properties.
+ ///
+ /// This defines are used by:
+ /// - @ref kodi::addon::CInstancePVRClient::GetChannelStreamProperties()
+ /// - @ref kodi::addon::CInstancePVRClient::GetEPGTagStreamProperties()
+ /// - @ref kodi::addon::CInstancePVRClient::GetRecordingStreamProperties()
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ ///
+ /// PVR_ERROR CMyPVRInstance::GetChannelStreamProperties(const kodi::addon::PVRChannel& channel,
+ /// std::vector<PVRStreamProperty>& properties)
+ /// {
+ /// ...
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "inputstream.adaptive");
+ /// properties.emplace_back("inputstream.adaptive.manifest_type", "mpd");
+ /// properties.emplace_back("inputstream.adaptive.manifest_update_parameter", "full");
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_MIMETYPE, "application/xml+dash");
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ ///
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+
+ /// @brief the URL of the stream that should be played.
+ ///
+ #define PVR_STREAM_PROPERTY_STREAMURL "streamurl"
+
+ /// @brief To define in stream properties the name of the inputstream add-on
+ /// that should be used.
+ ///
+ /// Leave blank to use Kodi's built-in playing capabilities or to allow ffmpeg
+ /// to handle directly set to @ref PVR_STREAM_PROPERTY_VALUE_INPUTSTREAMFFMPEG.
+ ///
+ #define PVR_STREAM_PROPERTY_INPUTSTREAM STREAM_PROPERTY_INPUTSTREAM
+
+ /// @brief To define in stream properties the player the inputstream add-on
+ /// should use.
+ ///
+ /// Leave blank to use Kodi's built-in player selection mechanism.
+ /// Permitted values are:
+ /// - "videodefaultplayer"
+ /// - "audiodefaultplayer"
+ ///
+ #define PVR_STREAM_PROPERTY_INPUTSTREAM_PLAYER STREAM_PROPERTY_INPUTSTREAM_PLAYER
+
+ /// @brief Identification string for an input stream.
+ ///
+ /// This value can be used in addition to @ref PVR_STREAM_PROPERTY_INPUTSTREAM.
+ /// It is used to provide the respective inpustream addon with additional
+ /// identification.
+ ///
+ /// The difference between this and other stream properties is that it is also
+ /// passed in the associated @ref kodi::addon::CAddonBase::CreateInstance()
+ /// call.
+ ///
+ /// This makes it possible to select different processing classes within the
+ /// associated add-on.
+ ///
+ ///
+ ///---------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ ///
+ /// // On PVR instance of addon
+ /// PVR_ERROR CMyPVRInstance::GetChannelStreamProperties(const kodi::addon::PVRChannel& channel,
+ /// std::vector<PVRStreamProperty>& properties)
+ /// {
+ /// ...
+ /// // For here on example the inpustream is also inside the PVR addon
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "pvr.my_one");
+ /// properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM_INSTANCE_ID, "my_special_id_1");
+ /// return PVR_ERROR_NO_ERROR;
+ /// }
+ ///
+ /// ...
+ ///
+ /// // On CAddonBase part of addon
+ /// ADDON_STATUS CMyAddon::CreateInstanceEx(int instanceType,
+ /// std::string instanceID,
+ /// KODI_HANDLE instance,
+ /// KODI_HANDLE& addonInstance
+ /// const std::string& version)
+ /// {
+ /// if (instanceType == ADDON_INSTANCE_INPUTSTREAM)
+ /// {
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my special inputstream");
+ /// if (instanceID == "my_special_id_1")
+ /// addonInstance = new CMyPVRClientInstance_Type1(instance, version);
+ /// else if (instanceID == "my_special_id_2")
+ /// addonInstance = new CMyPVRClientInstance_Type2(instance, version);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// else if (...)
+ /// {
+ /// ...
+ /// }
+ /// return ADDON_STATUS_UNKNOWN;
+ /// }
+ ///
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ #define PVR_STREAM_PROPERTY_INPUTSTREAM_INSTANCE_ID STREAM_PROPERTY_INPUTSTREAM_INSTANCE_ID
+
+ /// @brief the MIME type of the stream that should be played.
+ ///
+ #define PVR_STREAM_PROPERTY_MIMETYPE "mimetype"
+
+ /// @brief <b>"true"</b> to denote that the stream that should be played is a
+ /// realtime stream.
+ ///
+ /// Any other value indicates that this is no realtime stream.
+ ///
+ #define PVR_STREAM_PROPERTY_ISREALTIMESTREAM STREAM_PROPERTY_ISREALTIMESTREAM
+
+ /// @brief <b>"true"</b> to denote that if the stream is from an EPG tag.
+ ///
+ /// It should be played is a live stream. Otherwise if it's a EPG tag it will
+ /// play as normal video.
+ ///
+ #define PVR_STREAM_PROPERTY_EPGPLAYBACKASLIVE "epgplaybackaslive"
+
+ /// @brief Special value for @ref PVR_STREAM_PROPERTY_INPUTSTREAM to use
+ /// ffmpeg to directly play a stream URL.
+ #define PVR_STREAM_PROPERTY_VALUE_INPUTSTREAMFFMPEG STREAM_PROPERTY_VALUE_INPUTSTREAMFFMPEG
+
+ ///@}
+ //-----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on capabilities.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRCapabilities for description of values.
+ */
+ typedef struct PVR_ADDON_CAPABILITIES
+ {
+ bool bSupportsEPG;
+ bool bSupportsEPGEdl;
+ bool bSupportsTV;
+ bool bSupportsRadio;
+ bool bSupportsRecordings;
+ bool bSupportsRecordingsUndelete;
+ bool bSupportsTimers;
+ bool bSupportsChannelGroups;
+ bool bSupportsChannelScan;
+ bool bSupportsChannelSettings;
+ bool bHandlesInputStream;
+ bool bHandlesDemuxing;
+ bool bSupportsRecordingPlayCount;
+ bool bSupportsLastPlayedPosition;
+ bool bSupportsRecordingEdl;
+ bool bSupportsRecordingsRename;
+ bool bSupportsRecordingsLifetimeChange;
+ bool bSupportsDescrambleInfo;
+ bool bSupportsAsyncEPGTransfer;
+ bool bSupportsRecordingSize;
+ bool bSupportsProviders;
+ bool bSupportsRecordingsDelete;
+
+ unsigned int iRecordingsLifetimesSize;
+ struct PVR_ATTRIBUTE_INT_VALUE recordingsLifetimeValues[PVR_ADDON_ATTRIBUTE_VALUES_ARRAY_SIZE];
+ } PVR_ADDON_CAPABILITIES;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_GENERAL_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_menu_hook.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_menu_hook.h
new file mode 100644
index 0000000..e204311
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_menu_hook.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_MENUHOOK_H
+#define C_API_ADDONINSTANCE_PVR_MENUHOOK_H
+
+#include "pvr_defines.h"
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 7 - Menu hook
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Menuhook_PVR_MENUHOOK_CAT enum PVR_MENUHOOK_CAT
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Menuhook
+ /// @brief **PVR context menu hook categories**\n
+ /// Possible menu types given to Kodi with @ref kodi::addon::CInstancePVRClient::AddMenuHook().
+ ///
+ ///@{
+ typedef enum PVR_MENUHOOK_CAT
+ {
+ /// @brief __-1__ : Unknown menu hook.
+ PVR_MENUHOOK_UNKNOWN = -1,
+
+ /// @brief __0__ : All categories.
+ PVR_MENUHOOK_ALL = 0,
+
+ /// @brief __1__ : For channels.
+ PVR_MENUHOOK_CHANNEL = 1,
+
+ /// @brief __2__ : For timers.
+ PVR_MENUHOOK_TIMER = 2,
+
+ /// @brief __3__ : For EPG.
+ PVR_MENUHOOK_EPG = 3,
+
+ /// @brief __4__ : For recordings.
+ PVR_MENUHOOK_RECORDING = 4,
+
+ /// @brief __5__ : For deleted recordings.
+ PVR_MENUHOOK_DELETED_RECORDING = 5,
+
+ /// @brief __6__ : For settings.
+ PVR_MENUHOOK_SETTING = 6,
+ } PVR_MENUHOOK_CAT;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on menu hook.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRMenuhook for description of values.
+ */
+ typedef struct PVR_MENUHOOK
+ {
+ unsigned int iHookId;
+ unsigned int iLocalizedStringId;
+ enum PVR_MENUHOOK_CAT category;
+ } PVR_MENUHOOK;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_MENUHOOK_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_providers.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_providers.h
new file mode 100644
index 0000000..b1744aa
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_providers.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_PROVIDERS_H
+#define C_API_ADDONINSTANCE_PVR_PROVIDERS_H
+
+#include "pvr_defines.h"
+
+#include <stdbool.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 2 - PVR providers
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Provider
+ /// @brief Denotes that no provider uid is available.
+ ///
+ /// Special @ref kodi::addon::PVRChannel::SetClientProviderUid()
+ #define PVR_PROVIDER_INVALID_UID -1
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Provider
+ /// @brief Separator to use in strings containing different tokens, for example
+ /// country and language.
+ ///
+ #define PROVIDER_STRING_TOKEN_SEPARATOR ","
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Channel_PVR_PROVIDER_TYPE enum PVR_PROVIDER_TYPE
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Channel
+ /// @brief **PVR provider types**\n
+ /// Used on @ref kodi::addon::PVRProvider:SetProviderType() value to set related
+ /// type.
+ ///
+ ///@{
+ typedef enum PVR_PROVIDER_TYPE
+ {
+ /// @brief __0__ : Unknown type.
+ PVR_PROVIDER_TYPE_UNKNOWN = 0,
+
+ /// @brief __1__ : IPTV provider.
+ PVR_PROVIDER_TYPE_ADDON = 1,
+
+ /// @brief __2__ : Satellite provider.
+ PVR_PROVIDER_TYPE_SATELLITE = 2,
+
+ /// @brief __3__ : Cable provider.
+ PVR_PROVIDER_TYPE_CABLE = 3,
+
+ /// @brief __4__ : Aerial provider.
+ PVR_PROVIDER_TYPE_AERIAL = 4,
+
+ /// @brief __5__ : IPTV provider.
+ PVR_PROVIDER_TYPE_IPTV = 5,
+
+ /// @brief __6__ : Other type of provider.
+ PVR_PROVIDER_TYPE_OTHER = 6,
+ } PVR_PROVIDER_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on provider.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRProvider for description of values.
+ */
+ typedef struct PVR_PROVIDER
+ {
+ unsigned int iUniqueId;
+ char strName[PVR_ADDON_NAME_STRING_LENGTH];
+ enum PVR_PROVIDER_TYPE type;
+ char strIconPath[PVR_ADDON_URL_STRING_LENGTH];
+ //! @brief ISO 3166 country codes, separated by PROVIDER_STRING_TOKEN_SEPARATOR
+ /// (e.g 'GB,IE,FR,CA'), an empty string means this value is undefined
+ char strCountries[PVR_ADDON_COUNTRIES_STRING_LENGTH];
+ //! @brief RFC 5646 language codes, separated by PROVIDER_STRING_TOKEN_SEPARATOR
+ /// (e.g. 'en_GB,fr_CA'), an empty string means this value is undefined
+ char strLanguages[PVR_ADDON_LANGUAGES_STRING_LENGTH];
+ } PVR_PROVIDER;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_PROVIDERS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_recordings.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_recordings.h
new file mode 100644
index 0000000..f04ef34
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_recordings.h
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_RECORDINGS_H
+#define C_API_ADDONINSTANCE_PVR_RECORDINGS_H
+
+#include "pvr_defines.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <time.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 5 - PVR recordings
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Recording_PVR_RECORDING_FLAG enum PVR_RECORDING_FLAG
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Recording
+ /// @brief **Bit field of independent flags associated with the EPG entry.**\n
+ /// Values used by @ref kodi::addon::PVRRecording::SetFlags().
+ ///
+ /// Here's example about the use of this:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRRecording tag;
+ /// tag.SetFlags(PVR_RECORDING_FLAG_IS_SERIES | PVR_RECORDING_FLAG_IS_PREMIERE);
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ typedef enum PVR_RECORDING_FLAG
+ {
+ /// @brief __0000 0000__ : Nothing special to say about this recording.
+ PVR_RECORDING_FLAG_UNDEFINED = 0,
+
+ /// @brief __0000 0001__ : This recording is part of a series.
+ PVR_RECORDING_FLAG_IS_SERIES = (1 << 0),
+
+ /// @brief __0000 0010__ : This recording will be flagged as new.
+ PVR_RECORDING_FLAG_IS_NEW = (1 << 1),
+
+ /// @brief __0000 0100__ : This recording will be flagged as a premiere.
+ PVR_RECORDING_FLAG_IS_PREMIERE = (1 << 2),
+
+ /// @brief __0000 1000__ : This recording will be flagged as a finale.
+ PVR_RECORDING_FLAG_IS_FINALE = (1 << 3),
+
+ /// @brief __0001 0000__ : This recording will be flagged as live.
+ PVR_RECORDING_FLAG_IS_LIVE = (1 << 4),
+ } PVR_RECORDING_FLAG;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ /// @brief Special @ref kodi::addon::PVRRecording::SetSeriesNumber() and
+ /// @ref kodi::addon::PVRRecording::SetEpisodeNumber() value to indicate it is
+ /// not to be used.
+ ///
+ /// Used if recording has no valid season and/or episode info.
+ ///
+ #define PVR_RECORDING_INVALID_SERIES_EPISODE EPG_TAG_INVALID_SERIES_EPISODE
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Recording_PVRRecording
+ /// @brief Value where set in background to inform that related part not used.
+ ///
+ /// Normally this related parts need not to set by this as it is default.
+ #define PVR_RECORDING_VALUE_NOT_AVAILABLE -1
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Recording_PVR_RECORDING_CHANNEL_TYPE enum PVR_RECORDING_CHANNEL_TYPE
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Recording
+ /// @brief **PVR recording channel types**\n
+ /// Used on @ref kodi::addon::PVRRecording::SetChannelType() value to set related
+ /// type.
+ ///
+ ///@{
+ typedef enum PVR_RECORDING_CHANNEL_TYPE
+ {
+ /// @brief __0__ : Unknown type.
+ PVR_RECORDING_CHANNEL_TYPE_UNKNOWN = 0,
+
+ /// @brief __1__ : TV channel.
+ PVR_RECORDING_CHANNEL_TYPE_TV = 1,
+
+ /// @brief __2__ : Radio channel.
+ PVR_RECORDING_CHANNEL_TYPE_RADIO = 2,
+ } PVR_RECORDING_CHANNEL_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on recording.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref kodi::addon::PVRRecording for description of values.
+ */
+ typedef struct PVR_RECORDING
+ {
+ char strRecordingId[PVR_ADDON_NAME_STRING_LENGTH];
+ char strTitle[PVR_ADDON_NAME_STRING_LENGTH];
+ char strEpisodeName[PVR_ADDON_NAME_STRING_LENGTH];
+ int iSeriesNumber;
+ int iEpisodeNumber;
+ int iYear;
+ char strDirectory[PVR_ADDON_URL_STRING_LENGTH];
+ char strPlotOutline[PVR_ADDON_DESC_STRING_LENGTH];
+ char strPlot[PVR_ADDON_DESC_STRING_LENGTH];
+ char strGenreDescription[PVR_ADDON_DESC_STRING_LENGTH];
+ char strChannelName[PVR_ADDON_NAME_STRING_LENGTH];
+ char strIconPath[PVR_ADDON_URL_STRING_LENGTH];
+ char strThumbnailPath[PVR_ADDON_URL_STRING_LENGTH];
+ char strFanartPath[PVR_ADDON_URL_STRING_LENGTH];
+ time_t recordingTime;
+ int iDuration;
+ int iPriority;
+ int iLifetime;
+ int iGenreType;
+ int iGenreSubType;
+ int iPlayCount;
+ int iLastPlayedPosition;
+ bool bIsDeleted;
+ unsigned int iEpgEventId;
+ int iChannelUid;
+ enum PVR_RECORDING_CHANNEL_TYPE channelType;
+ char strFirstAired[PVR_ADDON_DATE_STRING_LENGTH];
+ unsigned int iFlags;
+ int64_t sizeInBytes;
+ int iClientProviderUid;
+ char strProviderName[PVR_ADDON_NAME_STRING_LENGTH];
+ } PVR_RECORDING;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_RECORDINGS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_stream.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_stream.h
new file mode 100644
index 0000000..62a3cbd
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_stream.h
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_STREAM_H
+#define C_API_ADDONINSTANCE_PVR_STREAM_H
+
+#include "../inputstream/demux_packet.h"
+#include "pvr_defines.h"
+
+#include <stdint.h>
+#include <time.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 9 - PVR stream definitions (NOTE: Becomes replaced
+// in future by inputstream addon instance way)
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+ /// @brief Maximum of allowed streams
+ ///
+ #define PVR_STREAM_MAX_STREAMS 20
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+ /// @brief Invalid codec identifier
+ ///
+ #define PVR_INVALID_CODEC_ID 0
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+ /// @brief Invalid codec
+ ///
+ #define PVR_INVALID_CODEC \
+ { \
+ PVR_CODEC_TYPE_UNKNOWN, PVR_INVALID_CODEC_ID \
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVR_CODEC_TYPE enum PVR_CODEC_TYPE
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+ /// @brief **Inputstream types**\n
+ /// To identify type on stream.
+ ///
+ /// Used on @ref kodi::addon::PVRStreamProperties::SetCodecType and @ref kodi::addon::PVRStreamProperties::SetCodecType.
+ ///
+ ///@{
+ typedef enum PVR_CODEC_TYPE
+ {
+ /// @brief To set nothing defined.
+ PVR_CODEC_TYPE_UNKNOWN = -1,
+
+ /// @brief To identify @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties as Video.
+ PVR_CODEC_TYPE_VIDEO,
+
+ /// @brief To identify @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties as Audio.
+ PVR_CODEC_TYPE_AUDIO,
+
+ /// @brief To identify @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties as Data.
+ ///
+ /// With codec id related source identified.
+ PVR_CODEC_TYPE_DATA,
+
+ /// @brief To identify @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties as Subtitle.
+ PVR_CODEC_TYPE_SUBTITLE,
+
+ /// @brief To identify @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties as Radio RDS.
+ PVR_CODEC_TYPE_RDS,
+
+ /// @brief To identify @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties as Audio ID3 tags.
+ PVR_CODEC_TYPE_ID3,
+
+ PVR_CODEC_TYPE_NB
+ } PVR_CODEC_TYPE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Stream_PVR_CODEC struct PVR_CODEC
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Stream
+ /// @brief **Codec identification structure**\n
+ /// Identifier about stream between Kodi and addon.
+ ///
+ ///@{
+ typedef struct PVR_CODEC
+ {
+ /// @brief Used codec type for stream.
+ enum PVR_CODEC_TYPE codec_type;
+
+ /// @brief Related codec identifier, normally match the ffmpeg id's.
+ unsigned int codec_id;
+ } PVR_CODEC;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" Stream properties
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamProperties for description of values.
+ */
+ typedef struct PVR_STREAM_PROPERTIES
+ {
+ unsigned int iStreamCount;
+ struct PVR_STREAM
+ {
+ unsigned int iPID;
+ enum PVR_CODEC_TYPE iCodecType;
+ unsigned int iCodecId;
+ char strLanguage[4];
+ int iSubtitleInfo;
+ int iFPSScale;
+ int iFPSRate;
+ int iHeight;
+ int iWidth;
+ float fAspect;
+ int iChannels;
+ int iSampleRate;
+ int iBlockAlign;
+ int iBitRate;
+ int iBitsPerSample;
+ } stream[PVR_STREAM_MAX_STREAMS];
+ } PVR_STREAM_PROPERTIES;
+
+ /*!
+ * @brief "C" Times of playing stream (Live TV and recordings)
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref cpp_kodi_addon_pvr_Defs_Stream_PVRStreamTimes for description of values.
+ */
+ typedef struct PVR_STREAM_TIMES
+ {
+ time_t startTime;
+ int64_t ptsStart;
+ int64_t ptsBegin;
+ int64_t ptsEnd;
+ } PVR_STREAM_TIMES;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_STREAM_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_timers.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_timers.h
new file mode 100644
index 0000000..6cae33e
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_timers.h
@@ -0,0 +1,410 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_PVR_TIMERS_H
+#define C_API_ADDONINSTANCE_PVR_TIMERS_H
+
+#include "pvr_defines.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <time.h>
+
+//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+// "C" Definitions group 6 - PVR timers
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVR_TIMER_ definition PVR_TIMER (various)
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Timer
+ /// @brief **PVR timer various different definitions**\n
+ /// This mostly used on @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimer "kodi::addon::PVRTimer"
+ /// to define default or not available.
+ ///
+ ///@{
+
+ //============================================================================
+ /// @brief Numeric PVR timer type definitions (@ref kodi::addon::PVRTimer::SetTimerType()
+ /// values).
+ ///
+ /// "Null" value for a numeric timer type.
+ #define PVR_TIMER_TYPE_NONE 0
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Special @ref kodi::addon::PVRTimer::SetClientIndex() value to indicate
+ /// that a timer has not (yet) a valid client index.
+ ///
+ /// Timer has not (yet) a valid client index.
+ #define PVR_TIMER_NO_CLIENT_INDEX 0
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Special @ref kodi::addon::PVRTimer::SetParentClientIndex() value to
+ /// indicate that a timer has no parent.
+ ///
+ /// Timer has no parent; it was not scheduled by a repeating timer.
+ #define PVR_TIMER_NO_PARENT PVR_TIMER_NO_CLIENT_INDEX
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Special @ref kodi::addon::PVRTimer::SetEPGUid() value to indicate
+ /// that a timer has no EPG event uid.
+ ///
+ /// Timer has no EPG event unique identifier.
+ #define PVR_TIMER_NO_EPG_UID EPG_TAG_INVALID_UID
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Special @ref kodi::addon::PVRTimer::SetClientChannelUid() value to
+ /// indicate "any channel". Useful for some repeating timer types.
+ ///
+ /// denotes "any channel", not a specific one.
+ ///
+ #define PVR_TIMER_ANY_CHANNEL -1
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Value where set in background to inform that related part not used.
+ ///
+ /// Normally this related parts need not to set by this as it is default.
+ #define PVR_TIMER_VALUE_NOT_AVAILABLE -1
+ //----------------------------------------------------------------------------
+
+ ///@}
+ //----------------------------------------------------------------------------
+
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVR_TIMER_TYPES enum PVR_TIMER_TYPES
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Timer
+ /// @brief **PVR timer type attributes (@ref kodi::addon::PVRTimerType::SetAttributes() values).**\n
+ /// To defines the attributes for a type. These values are bit fields that can be
+ /// used together.
+ ///
+ ///--------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::addon::PVRTimerType tag;
+ /// tag.SetAttributes(PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_IS_REPEATING);
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ typedef enum PVR_TIMER_TYPES
+ {
+ /// @brief __0000 0000 0000 0000 0000 0000 0000 0000__ :\n Empty attribute value.
+ PVR_TIMER_TYPE_ATTRIBUTE_NONE = 0,
+
+ /// @brief __0000 0000 0000 0000 0000 0000 0000 0001__ :\n Defines whether this is a type for
+ /// manual (time-based) or epg-based timers.
+ PVR_TIMER_TYPE_IS_MANUAL = (1 << 0),
+
+ /// @brief __0000 0000 0000 0000 0000 0000 0000 0010__ :\n Defines whether this is a type for
+ /// repeating or one-shot timers.
+ PVR_TIMER_TYPE_IS_REPEATING = (1 << 1),
+
+ /// @brief __0000 0000 0000 0000 0000 0000 0000 0100__ :\n Timers of this type must not be edited
+ /// by Kodi.
+ PVR_TIMER_TYPE_IS_READONLY = (1 << 2),
+
+ /// @brief __0000 0000 0000 0000 0000 0000 0000 1000__ :\n Timers of this type must not be created
+ /// by Kodi. All other operations are allowed, though.
+ PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES = (1 << 3),
+
+ /// @brief __0000 0000 0000 0000 0000 0000 0001 0000__ :\n This type supports enabling/disabling
+ /// of the timer (@ref kodi::addon::PVRTimer::SetState() with
+ /// @ref PVR_TIMER_STATE_SCHEDULED | @ref PVR_TIMER_STATE_DISABLED).
+ PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE = (1 << 4),
+
+ /// @brief __0000 0000 0000 0000 0000 0000 0010 0000__ :\n This type supports channels
+ /// (@ref kodi::addon::PVRTimer::SetClientChannelUid()).
+ PVR_TIMER_TYPE_SUPPORTS_CHANNELS = (1 << 5),
+
+ /// @brief __0000 0000 0000 0000 0000 0000 0100 0000__ :\n This type supports a recording start
+ /// time (@ref kodi::addon::PVRTimer::SetStartTime()).
+ PVR_TIMER_TYPE_SUPPORTS_START_TIME = (1 << 6),
+
+ /// @brief __0000 0000 0000 0000 0000 0000 1000 0000__ :\n This type supports matching epg episode
+ /// title using@ref kodi::addon::PVRTimer::SetEPGSearchString().
+ PVR_TIMER_TYPE_SUPPORTS_TITLE_EPG_MATCH = (1 << 7),
+
+ /// @brief __0000 0000 0000 0000 0000 0001 0000 0000__ :\n This type supports matching "more" epg
+ /// data (not just episode title) using @ref kodi::addon::PVRTimer::SetEPGSearchString().
+ /// Setting @ref PVR_TIMER_TYPE_SUPPORTS_FULLTEXT_EPG_MATCH implies
+ /// @ref PVR_TIMER_TYPE_SUPPORTS_TITLE_EPG_MATCH.
+ PVR_TIMER_TYPE_SUPPORTS_FULLTEXT_EPG_MATCH = (1 << 8),
+
+ /// @brief __0000 0000 0000 0000 0000 0010 0000 0000__ :\n This type supports a first day the
+ /// timer gets active (@ref kodi::addon::PVRTimer::SetFirstDay()).
+ PVR_TIMER_TYPE_SUPPORTS_FIRST_DAY = (1 << 9),
+
+ /// @brief __0000 0000 0000 0000 0000 0100 0000 0000__ :\n This type supports weekdays for
+ /// defining the recording schedule (@ref kodi::addon::PVRTimer::SetWeekdays()).
+ PVR_TIMER_TYPE_SUPPORTS_WEEKDAYS = (1 << 10),
+
+ /// @brief __0000 0000 0000 0000 0000 1000 0000 0000__ :\n This type supports the <b>"record only new episodes"</b> feature
+ /// (@ref kodi::addon::PVRTimer::SetPreventDuplicateEpisodes()).
+ PVR_TIMER_TYPE_SUPPORTS_RECORD_ONLY_NEW_EPISODES = (1 << 11),
+
+ /// @brief __0000 0000 0000 0000 0001 0000 0000 0000__ :\n This type supports pre and post record time (@ref kodi::addon::PVRTimer::SetMarginStart(),
+ /// @ref kodi::addon::PVRTimer::SetMarginEnd()).
+ PVR_TIMER_TYPE_SUPPORTS_START_END_MARGIN = (1 << 12),
+
+ /// @brief __0000 0000 0000 0000 0010 0000 0000 0000__ :\n This type supports recording priority (@ref kodi::addon::PVRTimer::SetPriority()).
+ PVR_TIMER_TYPE_SUPPORTS_PRIORITY = (1 << 13),
+
+ /// @brief __0000 0000 0000 0000 0100 0000 0000 0000__ :\n This type supports recording lifetime (@ref kodi::addon::PVRTimer::SetLifetime()).
+ PVR_TIMER_TYPE_SUPPORTS_LIFETIME = (1 << 14),
+
+ /// @brief __0000 0000 0000 0000 1000 0000 0000 0000__ :\n This type supports placing recordings in user defined folders
+ /// (@ref kodi::addon::PVRTimer::SetDirectory()).
+ PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS = (1 << 15),
+
+ /// @brief __0000 0000 0000 0001 0000 0000 0000 0000__ :\n This type supports a list of recording groups
+ /// (@ref kodi::addon::PVRTimer::SetRecordingGroup()).
+ PVR_TIMER_TYPE_SUPPORTS_RECORDING_GROUP = (1 << 16),
+
+ /// @brief __0000 0000 0000 0010 0000 0000 0000 0000__ :\n This type supports a recording end time (@ref kodi::addon::PVRTimer::SetEndTime()).
+ PVR_TIMER_TYPE_SUPPORTS_END_TIME = (1 << 17),
+
+ /// @brief __0000 0000 0000 0100 0000 0000 0000 0000__ :\n Enables an 'Any Time' over-ride option for start time
+ /// (using @ref kodi::addon::PVRTimer::SetStartAnyTime()).
+ PVR_TIMER_TYPE_SUPPORTS_START_ANYTIME = (1 << 18),
+
+ /// @brief __0000 0000 0000 1000 0000 0000 0000 0000__ :\n Enables a separate <b>'Any Time'</b> over-ride for end time
+ /// (using @ref kodi::addon::PVRTimer::SetEndAnyTime()).
+ PVR_TIMER_TYPE_SUPPORTS_END_ANYTIME = (1 << 19),
+
+ /// @brief __0000 0000 0001 0000 0000 0000 0000 0000__ :\n This type supports specifying a maximum recordings setting'
+ /// (@ref kodi::addon::PVRTimer::SetMaxRecordings()).
+ PVR_TIMER_TYPE_SUPPORTS_MAX_RECORDINGS = (1 << 20),
+
+ /// @brief __0000 0000 0010 0000 0000 0000 0000 0000__ :\n This type should not appear on any create menus which don't
+ /// provide an associated @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "EPG tag".
+ PVR_TIMER_TYPE_REQUIRES_EPG_TAG_ON_CREATE = (1 << 21),
+
+ /// @brief __0000 0000 0100 0000 0000 0000 0000 0000__ :\n This type should not appear on any create menus which provide an
+ /// associated @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "EPG tag".
+ PVR_TIMER_TYPE_FORBIDS_EPG_TAG_ON_CREATE = (1 << 22),
+
+ /// @brief __0000 0000 1000 0000 0000 0000 0000 0000__ :\n This type should not appear on any create menus unless associated
+ /// with an @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "EPG tag" with
+ /// 'series' attributes.
+ ///
+ /// Following conditions allow this:
+ /// - @ref kodi::addon::PVREPGTag::SetFlags() have flag @ref EPG_TAG_FLAG_IS_SERIES
+ /// - @ref kodi::addon::PVREPGTag::SetSeriesNumber() > 0
+ /// - @ref kodi::addon::PVREPGTag::SetEpisodeNumber() > 0
+ /// - @ref kodi::addon::PVREPGTag::SetEpisodePartNumber() > 0
+ ///
+ /// Implies @ref PVR_TIMER_TYPE_REQUIRES_EPG_TAG_ON_CREATE.
+ PVR_TIMER_TYPE_REQUIRES_EPG_SERIES_ON_CREATE = (1 << 23),
+
+ /// @brief __0000 0001 0000 0000 0000 0000 0000 0000__ :\n This type supports 'any channel', for example when defining a timer
+ /// rule that should match any channel instead of a particular channel.
+ PVR_TIMER_TYPE_SUPPORTS_ANY_CHANNEL = (1 << 24),
+
+ /// @brief __0000 0010 0000 0000 0000 0000 0000 0000__ :\n This type should not appear on any create menus which don't provide
+ /// an associated @ref cpp_kodi_addon_pvr_Defs_epg_PVREPGTag "EPG tag" with
+ /// a series link.
+ PVR_TIMER_TYPE_REQUIRES_EPG_SERIESLINK_ON_CREATE = (1 << 25),
+
+ /// @brief __0000 0100 0000 0000 0000 0000 0000 0000__ :\n This type allows deletion of an otherwise read-only timer.
+ PVR_TIMER_TYPE_SUPPORTS_READONLY_DELETE = (1 << 26),
+
+ /// @brief __0000 1000 0000 0000 0000 0000 0000 0000__ :\n Timers of this type do trigger a reminder if time is up.
+ PVR_TIMER_TYPE_IS_REMINDER = (1 << 27),
+
+ /// @brief __0001 0000 0000 0000 0000 0000 0000 0000__ :\n This type supports pre record time (@ref kodi::addon::PVRTimer::SetMarginStart()).
+ PVR_TIMER_TYPE_SUPPORTS_START_MARGIN = (1 << 28),
+
+ /// @brief __0010 0000 0000 0000 0000 0000 0000 0000__ :\n This type supports post record time (@ref kodi::addon::PVRTimer::SetMarginEnd()).
+ PVR_TIMER_TYPE_SUPPORTS_END_MARGIN = (1 << 29),
+ } PVR_TIMER_TYPES;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVR_WEEKDAY enum PVR_WEEKDAY
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Timer
+ /// @brief **PVR timer weekdays** (@ref kodi::addon::PVRTimer::SetWeekdays() **values**)\n
+ /// Used to select the days of a week you want.
+ ///
+ /// It can be also used to select several days e.g.:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ /// unsigned int day = PVR_WEEKDAY_MONDAY | PVR_WEEKDAY_SATURDAY;
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ typedef enum PVR_WEEKDAYS
+ {
+ /// @brief __0000 0000__ : Nothing selected.
+ PVR_WEEKDAY_NONE = 0,
+
+ /// @brief __0000 0001__ : To select Monday.
+ PVR_WEEKDAY_MONDAY = (1 << 0),
+
+ /// @brief __0000 0010__ : To select Tuesday.
+ PVR_WEEKDAY_TUESDAY = (1 << 1),
+
+ /// @brief __0000 0100__ : To select Wednesday.
+ PVR_WEEKDAY_WEDNESDAY = (1 << 2),
+
+ /// @brief __0000 1000__ : To select Thursday.
+ PVR_WEEKDAY_THURSDAY = (1 << 3),
+
+ /// @brief __0001 0000__ : To select Friday.
+ PVR_WEEKDAY_FRIDAY = (1 << 4),
+
+ /// @brief __0010 0000__ : To select Saturday.
+ PVR_WEEKDAY_SATURDAY = (1 << 5),
+
+ /// @brief __0100 0000__ : To select Sunday.
+ PVR_WEEKDAY_SUNDAY = (1 << 6),
+
+ /// @brief __0111 1111__ : To select all days of week.
+ PVR_WEEKDAY_ALLDAYS = PVR_WEEKDAY_MONDAY | PVR_WEEKDAY_TUESDAY | PVR_WEEKDAY_WEDNESDAY |
+ PVR_WEEKDAY_THURSDAY | PVR_WEEKDAY_FRIDAY | PVR_WEEKDAY_SATURDAY |
+ PVR_WEEKDAY_SUNDAY
+ } PVR_WEEKDAY;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_pvr_Defs_Timer_PVR_TIMER_STATE enum PVR_TIMER_STATE
+ /// @ingroup cpp_kodi_addon_pvr_Defs_Timer
+ /// @brief **PVR timer states**\n
+ /// To set within @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimer "kodi::addon::PVRTimer"
+ /// the needed state about.
+ ///
+ ///@{
+ typedef enum PVR_TIMER_STATE
+ {
+ /// @brief __0__ : The timer was just created on the backend and is not yet active.
+ ///
+ /// This state must not be used for timers just created on the client side.
+ PVR_TIMER_STATE_NEW = 0,
+
+ /// @brief __1__ : The timer is scheduled for recording.
+ PVR_TIMER_STATE_SCHEDULED = 1,
+
+ /// @brief __2__ : The timer is currently recordings.
+ PVR_TIMER_STATE_RECORDING = 2,
+
+ /// @brief __3__ : The recording completed successfully.
+ PVR_TIMER_STATE_COMPLETED = 3,
+
+ /// @brief __4__ : Recording started, but was aborted.
+ PVR_TIMER_STATE_ABORTED = 4,
+
+ /// @brief __5__ : The timer was scheduled, but was canceled.
+ PVR_TIMER_STATE_CANCELLED = 5,
+
+ /// @brief __6__ : The scheduled timer conflicts with another one, but will be
+ /// recorded.
+ PVR_TIMER_STATE_CONFLICT_OK = 6,
+
+ /// @brief __7__ : The scheduled timer conflicts with another one and won't be
+ /// recorded.
+ PVR_TIMER_STATE_CONFLICT_NOK = 7,
+
+ /// @brief __8__ : The timer is scheduled, but can't be recorded for some reason.
+ PVR_TIMER_STATE_ERROR = 8,
+
+ /// @brief __9__ : The timer was disabled by the user, can be enabled via setting
+ /// the state to @ref PVR_TIMER_STATE_SCHEDULED.
+ PVR_TIMER_STATE_DISABLED = 9,
+ } PVR_TIMER_STATE;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief "C" PVR add-on timer event.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimer "kodi::addon::PVRTimer" for
+ * description of values.
+ */
+ typedef struct PVR_TIMER
+ {
+ unsigned int iClientIndex;
+ unsigned int iParentClientIndex;
+ int iClientChannelUid;
+ time_t startTime;
+ time_t endTime;
+ bool bStartAnyTime;
+ bool bEndAnyTime;
+ enum PVR_TIMER_STATE state;
+ unsigned int iTimerType;
+ char strTitle[PVR_ADDON_NAME_STRING_LENGTH];
+ char strEpgSearchString[PVR_ADDON_NAME_STRING_LENGTH];
+ bool bFullTextEpgSearch;
+ char strDirectory[PVR_ADDON_URL_STRING_LENGTH];
+ char strSummary[PVR_ADDON_DESC_STRING_LENGTH];
+ int iPriority;
+ int iLifetime;
+ int iMaxRecordings;
+ unsigned int iRecordingGroup;
+ time_t firstDay;
+ unsigned int iWeekdays;
+ unsigned int iPreventDuplicateEpisodes;
+ unsigned int iEpgUid;
+ unsigned int iMarginStart;
+ unsigned int iMarginEnd;
+ int iGenreType;
+ int iGenreSubType;
+ char strSeriesLink[PVR_ADDON_URL_STRING_LENGTH];
+ } PVR_TIMER;
+
+ /*!
+ * @brief "C" PVR add-on timer event type.
+ *
+ * Structure used to interface in "C" between Kodi and Addon.
+ *
+ * See @ref cpp_kodi_addon_pvr_Defs_Timer_PVRTimerType "kodi::addon::PVRTimerType" for
+ * description of values.
+ */
+ typedef struct PVR_TIMER_TYPE
+ {
+ unsigned int iId;
+ uint64_t iAttributes;
+ char strDescription[PVR_ADDON_TIMERTYPE_STRING_LENGTH];
+
+ unsigned int iPrioritiesSize;
+ struct PVR_ATTRIBUTE_INT_VALUE priorities[PVR_ADDON_TIMERTYPE_VALUES_ARRAY_SIZE];
+ int iPrioritiesDefault;
+
+ unsigned int iLifetimesSize;
+ struct PVR_ATTRIBUTE_INT_VALUE lifetimes[PVR_ADDON_TIMERTYPE_VALUES_ARRAY_SIZE];
+ int iLifetimesDefault;
+
+ unsigned int iPreventDuplicateEpisodesSize;
+ struct PVR_ATTRIBUTE_INT_VALUE preventDuplicateEpisodes[PVR_ADDON_TIMERTYPE_VALUES_ARRAY_SIZE];
+ unsigned int iPreventDuplicateEpisodesDefault;
+
+ unsigned int iRecordingGroupSize;
+ struct PVR_ATTRIBUTE_INT_VALUE recordingGroup[PVR_ADDON_TIMERTYPE_VALUES_ARRAY_SIZE];
+ unsigned int iRecordingGroupDefault;
+
+ unsigned int iMaxRecordingsSize;
+ struct PVR_ATTRIBUTE_INT_VALUE maxRecordings[PVR_ADDON_TIMERTYPE_VALUES_ARRAY_SIZE_SMALL];
+ int iMaxRecordingsDefault;
+ } PVR_TIMER_TYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_PVR_TIMERS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/screensaver.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/screensaver.h
new file mode 100644
index 0000000..df1eb19
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/screensaver.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_SCREENSAVER_H
+#define C_API_ADDONINSTANCE_SCREENSAVER_H
+
+#include "../addon_base.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef KODI_ADDON_INSTANCE_HDL KODI_ADDON_SCREENSAVER_HDL;
+
+ struct KODI_ADDON_SCREENSAVER_PROPS
+ {
+ ADDON_HARDWARE_CONTEXT device;
+ int x;
+ int y;
+ int width;
+ int height;
+ float pixelRatio;
+ };
+
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_SCREENSAVER_START_V1)(
+ const KODI_ADDON_SCREENSAVER_HDL hdl);
+ typedef void(ATTR_APIENTRYP PFN_KODI_ADDON_SCREENSAVER_STOP_V1)(
+ const KODI_ADDON_SCREENSAVER_HDL hdl);
+ typedef void(ATTR_APIENTRYP PFN_KODI_ADDON_SCREENSAVER_RENDER_V1)(
+ const KODI_ADDON_SCREENSAVER_HDL hdl);
+
+ typedef struct KodiToAddonFuncTable_Screensaver
+ {
+ PFN_KODI_ADDON_SCREENSAVER_START_V1 start;
+ PFN_KODI_ADDON_SCREENSAVER_STOP_V1 stop;
+ PFN_KODI_ADDON_SCREENSAVER_RENDER_V1 render;
+ } KodiToAddonFuncTable_Screensaver;
+
+ typedef struct AddonToKodiFuncTable_Screensaver
+ {
+ void (*get_properties)(const KODI_HANDLE hdl, struct KODI_ADDON_SCREENSAVER_PROPS* props);
+ } AddonToKodiFuncTable_Screensaver;
+
+ typedef struct AddonInstance_Screensaver
+ {
+ struct AddonToKodiFuncTable_Screensaver* toKodi;
+ struct KodiToAddonFuncTable_Screensaver* toAddon;
+ } AddonInstance_Screensaver;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_SCREENSAVER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/vfs.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/vfs.h
new file mode 100644
index 0000000..b4fd90c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/vfs.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#ifndef C_API_ADDONINSTANCE_VFS_H
+#define C_API_ADDONINSTANCE_VFS_H
+
+#include "../addon_base.h"
+#include "../filesystem.h"
+
+#define VFS_FILE_HANDLE void*
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ struct VFSURL
+ {
+ const char* url;
+ const char* domain;
+ const char* hostname;
+ const char* filename;
+ unsigned int port;
+ const char* options;
+ const char* username;
+ const char* password;
+ const char* redacted;
+ const char* sharename;
+ const char* protocol;
+ };
+
+ typedef struct VFSGetDirectoryCallbacks /* internal */
+ {
+ bool(__cdecl* get_keyboard_input)(KODI_HANDLE ctx,
+ const char* heading,
+ char** input,
+ bool hidden_input);
+ void(__cdecl* set_error_dialog)(KODI_HANDLE ctx,
+ const char* heading,
+ const char* line1,
+ const char* line2,
+ const char* line3);
+ void(__cdecl* require_authentication)(KODI_HANDLE ctx, const char* url);
+ KODI_HANDLE ctx;
+ } VFSGetDirectoryCallbacks;
+
+ typedef struct AddonProps_VFSEntry /* internal */
+ {
+ int dummy;
+ } AddonProps_VFSEntry;
+
+ typedef struct AddonToKodiFuncTable_VFSEntry /* internal */
+ {
+ KODI_HANDLE kodiInstance;
+ } AddonToKodiFuncTable_VFSEntry;
+
+ struct AddonInstance_VFSEntry;
+ typedef struct KodiToAddonFuncTable_VFSEntry /* internal */
+ {
+ KODI_HANDLE addonInstance;
+
+ VFS_FILE_HANDLE(__cdecl* open)
+ (const struct AddonInstance_VFSEntry* instance, const struct VFSURL* url);
+ VFS_FILE_HANDLE(__cdecl* open_for_write)
+ (const struct AddonInstance_VFSEntry* instance, const struct VFSURL* url, bool overwrite);
+ ssize_t(__cdecl* read)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ uint8_t* buffer,
+ size_t buf_size);
+ ssize_t(__cdecl* write)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ const uint8_t* buffer,
+ size_t buf_size);
+ int64_t(__cdecl* seek)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ int64_t position,
+ int whence);
+ int(__cdecl* truncate)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ int64_t size);
+ int64_t(__cdecl* get_length)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context);
+ int64_t(__cdecl* get_position)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context);
+ int(__cdecl* get_chunk_size)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context);
+ bool(__cdecl* io_control_get_seek_possible)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context);
+ bool(__cdecl* io_control_get_cache_status)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ struct VFS_CACHE_STATUS_DATA* status);
+ bool(__cdecl* io_control_set_cache_rate)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ uint32_t rate);
+ bool(__cdecl* io_control_set_retry)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ bool retry);
+ int(__cdecl* stat)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url,
+ struct STAT_STRUCTURE* buffer);
+ bool(__cdecl* close)(const struct AddonInstance_VFSEntry* instance, VFS_FILE_HANDLE context);
+
+ bool(__cdecl* exists)(const struct AddonInstance_VFSEntry* instance, const struct VFSURL* url);
+ void(__cdecl* clear_out_idle)(const struct AddonInstance_VFSEntry* instance);
+ void(__cdecl* disconnect_all)(const struct AddonInstance_VFSEntry* instance);
+ bool(__cdecl* delete_it)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url);
+ bool(__cdecl* rename)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url,
+ const struct VFSURL* url2);
+ bool(__cdecl* directory_exists)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url);
+ bool(__cdecl* remove_directory)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url);
+ bool(__cdecl* create_directory)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url);
+ bool(__cdecl* get_directory)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url,
+ struct VFSDirEntry** entries,
+ int* num_entries,
+ struct VFSGetDirectoryCallbacks* callbacks);
+ bool(__cdecl* contains_files)(const struct AddonInstance_VFSEntry* instance,
+ const struct VFSURL* url,
+ struct VFSDirEntry** entries,
+ int* num_entries,
+ char* rootpath);
+ void(__cdecl* free_directory)(const struct AddonInstance_VFSEntry* instance,
+ struct VFSDirEntry* entries,
+ int num_entries);
+ } KodiToAddonFuncTable_VFSEntry;
+
+ typedef struct AddonInstance_VFSEntry /* internal */
+ {
+ struct AddonProps_VFSEntry* props;
+ struct AddonToKodiFuncTable_VFSEntry* toKodi;
+ struct KodiToAddonFuncTable_VFSEntry* toAddon;
+ } AddonInstance_VFSEntry;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_VFS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/video_codec.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/video_codec.h
new file mode 100644
index 0000000..0a70c15
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/video_codec.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2017-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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_VIDEOCODEC_H
+#define C_API_ADDONINSTANCE_VIDEOCODEC_H
+
+#include "../addon_base.h"
+#include "inputstream/demux_packet.h"
+#include "inputstream/stream_codec.h"
+#include "inputstream/stream_crypto.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec_Defs
+ /// @brief Return values used by video decoder interface
+ enum VIDEOCODEC_RETVAL
+ {
+ /// @brief Noop
+ VC_NONE = 0,
+
+ /// @brief An error occurred, no other messages will be returned
+ VC_ERROR,
+
+ /// @brief The decoder needs more data
+ VC_BUFFER,
+
+ /// @brief The decoder got a picture
+ VC_PICTURE,
+
+ /// @brief The decoder signals EOF
+ VC_EOF,
+ };
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata
+ /// @brief The video stream representations requested by Kodi
+ ///
+ enum VIDEOCODEC_FORMAT
+ {
+ /// @brief Unknown types, this is used to declare the end of a list of
+ /// requested types
+ VIDEOCODEC_FORMAT_UNKNOWN = 0,
+
+ /// @brief YV12 4:2:0 YCrCb planar format
+ VIDEOCODEC_FORMAT_YV12,
+
+ /// @brief These formats are identical to YV12 except that the U and V plane
+ /// order is reversed.
+ VIDEOCODEC_FORMAT_I420,
+
+ /// @brief The maximum value to use in a list.
+ VIDEOCODEC_FORMAT_MAXFORMATS
+ };
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec_Defs_VideoCodecInitdata
+ /// @brief Video codec types that can be requested from Kodi
+ ///
+ enum VIDEOCODEC_TYPE
+ {
+ /// @brief Unknown or other type requested
+ ///
+ VIDEOCODEC_UNKNOWN = 0,
+
+ /// @brief [VP8](https://en.wikipedia.org/wiki/VP8) video coding format
+ ///
+ VIDEOCODEC_VP8,
+
+ /// @brief [Advanced Video Coding (AVC)](https://en.wikipedia.org/wiki/Advanced_Video_Coding),
+ /// also referred to as H.264 or [MPEG-4](https://en.wikipedia.org/wiki/MPEG-4)
+ /// Part 10, Advanced Video Coding (MPEG-4 AVC).
+ VIDEOCODEC_H264,
+
+ /// @brief [VP9](https://en.wikipedia.org/wiki/VP9) video coding format\n
+ /// \n
+ /// VP9 is the successor to VP8 and competes mainly with MPEG's
+ /// [High Efficiency Video Coding](https://en.wikipedia.org/wiki/High_Efficiency_Video_Coding)
+ /// (HEVC/H.265).
+ VIDEOCODEC_VP9,
+
+ /// @brief [AV1](https://en.wikipedia.org/wiki/AV1) video coding format\n
+ /// \n
+ /// AV1 is the successor to VP9 and competes mainly with MPEG's
+ /// [High Efficiency Video Coding](https://en.wikipedia.org/wiki/High_Efficiency_Video_Coding)
+ /// (HEVC/H.265).
+ VIDEOCODEC_AV1,
+ };
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec_Defs_VIDEOCODEC_PICTURE
+ /// @brief YUV Plane identification pointers
+ ///
+ /// YUV is a color encoding system typically used as part of a color image pipeline.
+ ///
+ /// These are used to access stored data in @ref VIDEOCODEC_PICTURE::planeOffsets
+ /// and @ref VIDEOCODEC_PICTURE::stride.
+ ///
+ enum VIDEOCODEC_PLANE
+ {
+ /// @brief "luminance" component Y (equivalent to grey scale)
+ VIDEOCODEC_PICTURE_Y_PLANE = 0,
+
+ /// @brief "chrominance" component U (blue projection)
+ VIDEOCODEC_PICTURE_U_PLANE,
+
+ /// @brief "chrominance" component V (red projection)
+ VIDEOCODEC_PICTURE_V_PLANE,
+
+ /// @brief The maximum value to use in a list.
+ VIDEOCODEC_PICTURE_MAXPLANES = 3,
+ };
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_videocodec_Defs_VIDEOCODEC_PICTURE
+ /// @brief Video coded process flags, used to perform special operations in
+ /// stream calls.
+ ///
+ /// These are used to access stored data in @ref VIDEOCODEC_PICTURE::flags.
+ ///
+ /// @note These variables are bit flags which are created using "|" can be used together.
+ ///
+ enum VIDEOCODEC_PICTURE_FLAG
+ {
+ /// @brief Empty and nothing defined
+ VIDEOCODEC_PICTURE_FLAG_NONE = 0,
+
+ /// @brief Drop in decoder
+ VIDEOCODEC_PICTURE_FLAG_DROP = (1 << 0),
+
+ /// @brief Squeeze out pictured without feeding new packets
+ VIDEOCODEC_PICTURE_FLAG_DRAIN = (1 << 1),
+ };
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_videocodec_Defs_VIDEOCODEC_PICTURE struct VIDEOCODEC_PICTURE
+ /// @ingroup cpp_kodi_addon_videocodec_Defs
+ /// @brief Data structure which is given to the addon when a decoding call is made.
+ ///
+ ///@{
+ struct VIDEOCODEC_PICTURE
+ {
+ /// @brief The video format declared with @ref VIDEOCODEC_FORMAT and to be
+ /// used on the addon.
+ enum VIDEOCODEC_FORMAT videoFormat;
+
+ /// @brief Video coded process flags, used to perform special operations in
+ /// stream calls.
+ ///
+ /// Possible flags are declared here @ref VIDEOCODEC_PICTURE_FLAGS.
+ uint32_t flags;
+
+ /// @brief Picture width.
+ uint32_t width;
+
+ /// @brief Picture height.
+ uint32_t height;
+
+ /// @brief Data to be decoded in the addon.
+ uint8_t* decodedData;
+
+ /// @brief Size of the data given with @ref decodedData
+ size_t decodedDataSize;
+
+ /// @brief YUV color plane calculation array.
+ ///
+ /// This includes the three values of the YUV and can be identified using
+ /// @ref VIDEOCODEC_PLANE.
+ uint32_t planeOffsets[VIDEOCODEC_PICTURE_MAXPLANES];
+
+ /// @brief YUV color stride calculation array
+ ///
+ /// This includes the three values of the YUV and can be identified using
+ /// @ref VIDEOCODEC_PLANE.
+ uint32_t stride[VIDEOCODEC_PICTURE_MAXPLANES];
+
+ /// @brief Picture presentation time stamp (PTS).
+ int64_t pts;
+
+ /// @brief This is used to save the related handle from Kodi.
+ ///
+ /// To handle the input stream buffer, this is given by Kodi using
+ /// @ref kodi::addon::CInstanceVideoCodec::GetFrameBuffer and must be
+ /// released again using @ref kodi::addon::CInstanceVideoCodec::ReleaseFrameBuffer.
+ KODI_HANDLE videoBufferHandle;
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ struct VIDEOCODEC_INITDATA
+ {
+ enum VIDEOCODEC_TYPE codec;
+ enum STREAMCODEC_PROFILE codecProfile;
+ enum VIDEOCODEC_FORMAT* videoFormats;
+ uint32_t width;
+ uint32_t height;
+ const uint8_t* extraData;
+ unsigned int extraDataSize;
+ struct STREAM_CRYPTO_SESSION cryptoSession;
+ };
+
+ // this are properties given to the addon on create
+ // at this time we have no parameters for the addon
+ typedef struct AddonProps_VideoCodec
+ {
+ int dummy;
+ } AddonProps_VideoCodec;
+
+ struct AddonInstance_VideoCodec;
+ typedef struct KodiToAddonFuncTable_VideoCodec
+ {
+ KODI_HANDLE addonInstance;
+
+ //! @brief Opens a codec
+ bool(__cdecl* open)(const struct AddonInstance_VideoCodec* instance,
+ struct VIDEOCODEC_INITDATA* initData);
+
+ //! @brief Reconfigures a codec
+ bool(__cdecl* reconfigure)(const struct AddonInstance_VideoCodec* instance,
+ struct VIDEOCODEC_INITDATA* initData);
+
+ //! @brief Feed codec if requested from GetPicture() (return VC_BUFFER)
+ bool(__cdecl* add_data)(const struct AddonInstance_VideoCodec* instance,
+ const struct DEMUX_PACKET* packet);
+
+ //! @brief Get a decoded picture / request new data
+ enum VIDEOCODEC_RETVAL(__cdecl* get_picture)(const struct AddonInstance_VideoCodec* instance,
+ struct VIDEOCODEC_PICTURE* picture);
+
+ //! @brief Get the name of this video decoder
+ const char*(__cdecl* get_name)(const struct AddonInstance_VideoCodec* instance);
+
+ //! @brief Reset the codec
+ void(__cdecl* reset)(const struct AddonInstance_VideoCodec* instance);
+ } KodiToAddonFuncTable_VideoCodec;
+
+ typedef struct AddonToKodiFuncTable_VideoCodec
+ {
+ KODI_HANDLE kodiInstance;
+ bool (*get_frame_buffer)(void* kodiInstance, struct VIDEOCODEC_PICTURE* picture);
+ void (*release_frame_buffer)(void* kodiInstance, void* buffer);
+ } AddonToKodiFuncTable_VideoCodec;
+
+ typedef struct AddonInstance_VideoCodec
+ {
+ struct AddonProps_VideoCodec* props;
+ struct AddonToKodiFuncTable_VideoCodec* toKodi;
+ struct KodiToAddonFuncTable_VideoCodec* toAddon;
+ } AddonInstance_VideoCodec;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_VIDEOCODEC_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/visualization.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/visualization.h
new file mode 100644
index 0000000..ae5b2d0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/visualization.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_ADDONINSTANCE_VISUALIZATION_H
+#define C_API_ADDONINSTANCE_VISUALIZATION_H
+
+#include "../addon_base.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef KODI_ADDON_INSTANCE_HDL KODI_ADDON_VISUALIZATION_HDL;
+
+ struct KODI_ADDON_VISUALIZATION_TRACK
+ {
+ const char* title;
+ const char* artist;
+ const char* album;
+ const char* albumArtist;
+ const char* genre;
+ const char* comment;
+ const char* lyrics;
+
+ const char* reserved1;
+ const char* reserved2;
+
+ int trackNumber;
+ int discNumber;
+ int duration;
+ int year;
+ int rating;
+
+ int reserved3;
+ int reserved4;
+ };
+
+ struct KODI_ADDON_VISUALIZATION_PROPS
+ {
+ ADDON_HARDWARE_CONTEXT device;
+ int x;
+ int y;
+ int width;
+ int height;
+ float pixelRatio;
+ };
+
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_START_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl,
+ int channels,
+ int samples_per_sec,
+ int bits_per_sample,
+ const char* song_name);
+ typedef void(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_STOP_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+
+ typedef int(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_GET_SYNC_DELAY_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+
+ typedef void(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_AUDIO_DATA_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl, const float* audio_data, size_t audio_data_length);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_IS_DIRTY_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+ typedef void(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_RENDER_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+
+ typedef unsigned int(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_GET_PRESETS_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+ typedef int(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_GET_ACTIVE_PRESET_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_PREV_PRESET_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_NEXT_PRESET_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_LOAD_PRESET_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl, int select);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_RANDOM_PRESET_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_LOCK_PRESET_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_RATE_PRESET_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl, bool plus_minus);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_IS_LOCKED_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl);
+
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_UPDATE_ALBUMART_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl, const char* albumart);
+ typedef bool(ATTR_APIENTRYP PFN_KODI_ADDON_VISUALIZATION_UPDATE_TRACK_V1)(
+ const KODI_ADDON_VISUALIZATION_HDL hdl, const struct KODI_ADDON_VISUALIZATION_TRACK* track);
+
+ typedef struct KodiToAddonFuncTable_Visualization
+ {
+ PFN_KODI_ADDON_VISUALIZATION_START_V1 start;
+ PFN_KODI_ADDON_VISUALIZATION_STOP_V1 stop;
+
+ PFN_KODI_ADDON_VISUALIZATION_GET_SYNC_DELAY_V1 get_sync_delay;
+
+ PFN_KODI_ADDON_VISUALIZATION_AUDIO_DATA_V1 audio_data;
+ PFN_KODI_ADDON_VISUALIZATION_IS_DIRTY_V1 is_dirty;
+ PFN_KODI_ADDON_VISUALIZATION_RENDER_V1 render;
+
+ PFN_KODI_ADDON_VISUALIZATION_GET_PRESETS_V1 get_presets;
+ PFN_KODI_ADDON_VISUALIZATION_GET_ACTIVE_PRESET_V1 get_active_preset;
+ PFN_KODI_ADDON_VISUALIZATION_PREV_PRESET_V1 prev_preset;
+ PFN_KODI_ADDON_VISUALIZATION_NEXT_PRESET_V1 next_preset;
+ PFN_KODI_ADDON_VISUALIZATION_LOAD_PRESET_V1 load_preset;
+ PFN_KODI_ADDON_VISUALIZATION_RANDOM_PRESET_V1 random_preset;
+ PFN_KODI_ADDON_VISUALIZATION_LOCK_PRESET_V1 lock_preset;
+ PFN_KODI_ADDON_VISUALIZATION_RATE_PRESET_V1 rate_preset;
+ PFN_KODI_ADDON_VISUALIZATION_IS_LOCKED_V1 is_locked;
+
+ PFN_KODI_ADDON_VISUALIZATION_UPDATE_ALBUMART_V1 update_albumart;
+ PFN_KODI_ADDON_VISUALIZATION_UPDATE_TRACK_V1 update_track;
+ } KodiToAddonFuncTable_Visualization;
+
+ typedef struct AddonToKodiFuncTable_Visualization
+ {
+ void (*get_properties)(const KODI_HANDLE hdl, struct KODI_ADDON_VISUALIZATION_PROPS* props);
+ void (*transfer_preset)(const KODI_HANDLE hdl, const char* preset);
+ void (*clear_presets)(const KODI_HANDLE hdl);
+ } AddonToKodiFuncTable_Visualization;
+
+ typedef struct AddonInstance_Visualization
+ {
+ struct AddonToKodiFuncTable_Visualization* toKodi;
+ struct KodiToAddonFuncTable_Visualization* toAddon;
+ } AddonInstance_Visualization;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDONINSTANCE_VISUALIZATION_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon_base.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon_base.h
new file mode 100644
index 0000000..89403a3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon_base.h
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2005-2019 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.
+ */
+
+#ifndef C_API_ADDON_BASE_H
+#define C_API_ADDON_BASE_H
+
+#if !defined(NOMINMAX)
+#define NOMINMAX
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef TARGET_WINDOWS
+#ifndef __cdecl
+#define __cdecl
+#endif
+#ifndef __declspec
+#define __declspec(X)
+#endif
+#endif
+
+// Generic helper definitions for smallest possible alignment
+//@{
+#undef ATTR_PACKED
+#undef PRAGMA_PACK_BEGIN
+#undef PRAGMA_PACK_END
+
+#if defined(__GNUC__)
+#define ATTR_PACKED __attribute__((packed))
+#define PRAGMA_PACK 0
+#endif
+
+#if !defined(ATTR_PACKED)
+#define ATTR_PACKED
+#define PRAGMA_PACK 1
+#endif
+//@}
+
+// Generic helper definitions for inline function support
+//@{
+#ifdef _MSC_VER
+#define ATTR_FORCEINLINE __forceinline
+#elif defined(__GNUC__)
+#define ATTR_FORCEINLINE inline __attribute__((__always_inline__))
+#elif defined(__CLANG__)
+#if __has_attribute(__always_inline__)
+#define ATTR_FORCEINLINE inline __attribute__((__always_inline__))
+#else
+#define ATTR_FORCEINLINE inline
+#endif
+#else
+#define ATTR_FORCEINLINE inline
+#endif
+//@}
+
+// Generic helper definitions for shared library support
+//@{
+#if defined _WIN32 || defined _WIN64 || defined __CYGWIN__
+#define ATTR_DLL_IMPORT __declspec(dllimport)
+#define ATTR_DLL_EXPORT __declspec(dllexport)
+#define ATTR_DLL_LOCAL
+#ifdef _WIN64
+#define ATTR_APIENTRY __stdcall
+#else
+#define ATTR_APIENTRY __cdecl
+#endif
+#else
+#if __GNUC__ >= 4
+#define ATTR_DLL_IMPORT __attribute__((visibility("default")))
+#define ATTR_DLL_EXPORT __attribute__((visibility("default")))
+#ifndef SWIG
+#define ATTR_DLL_LOCAL __attribute__((visibility("hidden")))
+#else
+#define ATTR_DLL_LOCAL
+#endif
+#else
+#define ATTR_DLL_IMPORT
+#define ATTR_DLL_EXPORT
+#define ATTR_DLL_LOCAL
+#endif
+#define ATTR_APIENTRY
+#endif
+
+#ifndef ATTR_APIENTRYP
+#define ATTR_APIENTRYP ATTR_APIENTRY*
+#endif
+//@}
+
+#ifdef _WIN32 // windows
+#if !defined(_SSIZE_T_DEFINED) && !defined(HAVE_SSIZE_T)
+typedef intptr_t ssize_t;
+#define _SSIZE_T_DEFINED
+#endif // !_SSIZE_T_DEFINED
+#ifndef SSIZE_MAX
+#define SSIZE_MAX INTPTR_MAX
+#endif // !SSIZE_MAX
+#else // Linux, Mac, FreeBSD
+#include <sys/types.h>
+#endif // TARGET_POSIX
+
+/*
+ * To have a on add-on and kodi itself handled string always on known size!
+ */
+#define ADDON_STANDARD_STRING_LENGTH 1024
+#define ADDON_STANDARD_STRING_LENGTH_SMALL 256
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef void* KODI_ADDON_HDL;
+ typedef void* KODI_ADDON_BACKEND_HDL;
+ typedef void* KODI_ADDON_INSTANCE_HDL;
+ typedef void* KODI_ADDON_INSTANCE_BACKEND_HDL;
+
+ // Hardware specific device context interface
+ typedef void* ADDON_HARDWARE_CONTEXT;
+
+ typedef void* KODI_ADDON_FUNC_DUMMY;
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_addonbase_Defs
+ /// @defgroup cpp_kodi_addon_addonbase_Defs_ADDON_STATUS enum ADDON_STATUS
+ /// @brief <b>Return value of functions in @ref cpp_kodi_addon_addonbase "kodi::addon::CAddonBase"
+ /// and associated classes</b>\n
+ /// With this Kodi can do any follow-up work or add-on e.g. declare it as defective.
+ ///
+ ///@{
+ typedef enum ADDON_STATUS
+ {
+ /// @brief For everything OK and no error
+ ADDON_STATUS_OK,
+
+ /// @brief A needed connection was lost
+ ADDON_STATUS_LOST_CONNECTION,
+
+ /// @brief Addon needs a restart inside Kodi
+ ADDON_STATUS_NEED_RESTART,
+
+ /// @brief Necessary settings are not yet set
+ ADDON_STATUS_NEED_SETTINGS,
+
+ /// @brief Unknown and incomprehensible error
+ ADDON_STATUS_UNKNOWN,
+
+ /// @brief Permanent failure, like failing to resolve methods
+ ADDON_STATUS_PERMANENT_FAILURE,
+
+ /* internal used return error if function becomes not used from child on
+ * addon */
+ ADDON_STATUS_NOT_IMPLEMENTED
+ } ADDON_STATUS;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_Defs_ADDON_LOG enum ADDON_LOG
+ /// @ingroup cpp_kodi_Defs
+ /// @brief **Log file type definitions**\n
+ /// These define the types of log entries given with @ref kodi::Log() to Kodi.
+ ///
+ /// -------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/General.h>
+ ///
+ /// kodi::Log(ADDON_LOG_ERROR, "%s: There is an error occurred!", __func__);
+ ///
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ typedef enum ADDON_LOG
+ {
+ /// @brief **0** : To include debug information in the log file.
+ ADDON_LOG_DEBUG = 0,
+
+ /// @brief **1** : To include information messages in the log file.
+ ADDON_LOG_INFO = 1,
+
+ /// @brief **2** : To write warnings in the log file.
+ ADDON_LOG_WARNING = 2,
+
+ /// @brief **3** : To report error messages in the log file.
+ ADDON_LOG_ERROR = 3,
+
+ /// @brief **4** : To notify fatal unrecoverable errors, which can may also indicate
+ /// upcoming crashes.
+ ADDON_LOG_FATAL = 4
+ } ADDON_LOG;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_STRING_V1)(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, const char* value);
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_BOOLEAN_V1)(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, bool value);
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_INTEGER_V1)(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, int value);
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_FLOAT_V1)(
+ const KODI_ADDON_INSTANCE_HDL hdl, const char* name, float value);
+
+ typedef struct KODI_ADDON_INSTANCE_FUNC
+ {
+ PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_STRING_V1 instance_setting_change_string;
+ PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_BOOLEAN_V1 instance_setting_change_boolean;
+ PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_INTEGER_V1 instance_setting_change_integer;
+ PFN_KODI_ADDON_INSTANCE_SETTING_CHANGE_FLOAT_V1 instance_setting_change_float;
+ } KODI_ADDON_INSTANCE_FUNC;
+
+ typedef struct KODI_ADDON_INSTANCE_FUNC_CB
+ {
+ char* (*get_instance_user_path)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl);
+ bool (*is_instance_setting_using_default)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id);
+
+ bool (*get_instance_setting_bool)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ bool* value);
+ bool (*get_instance_setting_int)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ int* value);
+ bool (*get_instance_setting_float)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ float* value);
+ bool (*get_instance_setting_string)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ char** value);
+
+ bool (*set_instance_setting_bool)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ bool value);
+ bool (*set_instance_setting_int)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ int value);
+ bool (*set_instance_setting_float)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ float value);
+ bool (*set_instance_setting_string)(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
+ const char* id,
+ const char* value);
+ } KODI_ADDON_INSTANCE_FUNC_CB;
+
+ typedef int KODI_ADDON_INSTANCE_TYPE;
+
+ typedef struct KODI_ADDON_INSTANCE_INFO
+ {
+ KODI_ADDON_INSTANCE_TYPE type;
+ uint32_t number;
+ const char* id;
+ const char* version;
+ KODI_ADDON_INSTANCE_BACKEND_HDL kodi;
+ KODI_ADDON_INSTANCE_HDL parent;
+ bool first_instance;
+
+ struct KODI_ADDON_INSTANCE_FUNC_CB* functions;
+ } KODI_ADDON_INSTANCE_INFO;
+
+ typedef struct KODI_ADDON_INSTANCE_STRUCT
+ {
+ const KODI_ADDON_INSTANCE_INFO* info;
+
+ KODI_ADDON_INSTANCE_HDL hdl;
+ struct KODI_ADDON_INSTANCE_FUNC* functions;
+ union {
+ KODI_ADDON_FUNC_DUMMY dummy;
+ struct AddonInstance_AudioDecoder* audiodecoder;
+ struct AddonInstance_AudioEncoder* audioencoder;
+ struct AddonInstance_ImageDecoder* imagedecoder;
+ struct AddonInstance_Game* game;
+ struct AddonInstance_InputStream* inputstream;
+ struct AddonInstance_Peripheral* peripheral;
+ struct AddonInstance_PVR* pvr;
+ struct AddonInstance_Screensaver* screensaver;
+ struct AddonInstance_VFSEntry* vfs;
+ struct AddonInstance_VideoCodec* videocodec;
+ struct AddonInstance_Visualization* visualization;
+ };
+ } KODI_ADDON_INSTANCE_STRUCT;
+
+ /*! @brief Standard undefined pointer handle */
+ typedef void* KODI_HANDLE;
+
+ typedef struct AddonToKodiFuncTable_kodi_addon
+ {
+ char* (*get_addon_path)(const KODI_ADDON_BACKEND_HDL hdl);
+ char* (*get_lib_path)(const KODI_ADDON_BACKEND_HDL hdl);
+ char* (*get_user_path)(const KODI_ADDON_BACKEND_HDL hdl);
+ char* (*get_temp_path)(const KODI_ADDON_BACKEND_HDL hdl);
+
+ char* (*get_localized_string)(const KODI_ADDON_BACKEND_HDL hdl, long label_id);
+
+ bool (*open_settings_dialog)(const KODI_ADDON_BACKEND_HDL hdl);
+ bool (*is_setting_using_default)(const KODI_ADDON_BACKEND_HDL hdl, const char* id);
+
+ bool (*get_setting_bool)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, bool* value);
+ bool (*get_setting_int)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, int* value);
+ bool (*get_setting_float)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, float* value);
+ bool (*get_setting_string)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, char** value);
+
+ bool (*set_setting_bool)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, bool value);
+ bool (*set_setting_int)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, int value);
+ bool (*set_setting_float)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, float value);
+ bool (*set_setting_string)(const KODI_ADDON_BACKEND_HDL hdl, const char* id, const char* value);
+
+ char* (*get_addon_info)(const KODI_ADDON_BACKEND_HDL hdl, const char* id);
+
+ char* (*get_type_version)(const KODI_ADDON_BACKEND_HDL hdl, int type);
+ void* (*get_interface)(const KODI_ADDON_BACKEND_HDL hdl, const char* name, const char* version);
+ } AddonToKodiFuncTable_kodi_addon;
+
+ /*!
+ * @brief Callback function tables from addon to Kodi
+ * Set complete from Kodi!
+ */
+ typedef struct AddonToKodiFuncTable_Addon
+ {
+ // Pointer inside Kodi, used on callback functions to give related handle
+ // class, for this ADDON::CAddonDll inside Kodi.
+ KODI_ADDON_BACKEND_HDL kodiBase;
+
+ void (*free_string)(const KODI_ADDON_BACKEND_HDL hdl, char* str);
+ void (*free_string_array)(const KODI_ADDON_BACKEND_HDL hdl, char** arr, int numElements);
+ void (*addon_log_msg)(const KODI_ADDON_BACKEND_HDL hdl, const int loglevel, const char* msg);
+
+ struct AddonToKodiFuncTable_kodi* kodi;
+ struct AddonToKodiFuncTable_kodi_addon* kodi_addon;
+ struct AddonToKodiFuncTable_kodi_audioengine* kodi_audioengine;
+ struct AddonToKodiFuncTable_kodi_filesystem* kodi_filesystem;
+ struct AddonToKodiFuncTable_kodi_gui* kodi_gui;
+ struct AddonToKodiFuncTable_kodi_network* kodi_network;
+ } AddonToKodiFuncTable_Addon;
+
+ typedef ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_CREATE_V1)(
+ const KODI_ADDON_INSTANCE_BACKEND_HDL first_instance, KODI_ADDON_HDL* hdl);
+ typedef void(ATTR_APIENTRYP PFN_KODI_ADDON_DESTROY_V1)(const KODI_ADDON_HDL hdl);
+ typedef ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_CREATE_INSTANCE_V1)(
+ const KODI_ADDON_HDL hdl, struct KODI_ADDON_INSTANCE_STRUCT* instance);
+ typedef void(ATTR_APIENTRYP PFN_KODI_ADDON_DESTROY_INSTANCE_V1)(
+ const KODI_ADDON_HDL hdl, struct KODI_ADDON_INSTANCE_STRUCT* instance);
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_SETTING_CHANGE_STRING_V1)(
+ const KODI_ADDON_HDL hdl, const char* name, const char* value);
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_SETTING_CHANGE_BOOLEAN_V1)(
+ const KODI_ADDON_HDL hdl, const char* name, bool value);
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_SETTING_CHANGE_INTEGER_V1)(
+ const KODI_ADDON_HDL hdl, const char* name, int value);
+ typedef enum ADDON_STATUS(ATTR_APIENTRYP PFN_KODI_ADDON_SETTING_CHANGE_FLOAT_V1)(
+ const KODI_ADDON_HDL hdl, const char* name, float value);
+
+ /*!
+ * @brief Function tables from Kodi to addon
+ */
+ typedef struct KodiToAddonFuncTable_Addon
+ {
+ PFN_KODI_ADDON_CREATE_V1 create;
+ PFN_KODI_ADDON_DESTROY_V1 destroy;
+ PFN_KODI_ADDON_CREATE_INSTANCE_V1 create_instance;
+ PFN_KODI_ADDON_DESTROY_INSTANCE_V1 destroy_instance;
+ PFN_KODI_ADDON_SETTING_CHANGE_STRING_V1 setting_change_string;
+ PFN_KODI_ADDON_SETTING_CHANGE_BOOLEAN_V1 setting_change_boolean;
+ PFN_KODI_ADDON_SETTING_CHANGE_INTEGER_V1 setting_change_integer;
+ PFN_KODI_ADDON_SETTING_CHANGE_FLOAT_V1 setting_change_float;
+ } KodiToAddonFuncTable_Addon;
+
+ /*!
+ * @brief Main structure passed from kodi to addon with basic information needed to
+ * create add-on.
+ */
+ typedef struct AddonGlobalInterface
+ {
+ // Pointer of first created instance, used in case this add-on goes with single way
+ // Set from Kodi!
+ struct KODI_ADDON_INSTANCE_STRUCT* firstKodiInstance;
+
+ // Pointer to master base class inside add-on
+ // Set from addon header (kodi::addon::CAddonBase)!
+ KODI_ADDON_HDL addonBase;
+
+ // Pointer to a instance used on single way (together with this class)
+ // Set from addon header (kodi::addon::IAddonInstance)!
+ KODI_ADDON_INSTANCE_HDL globalSingleInstance;
+
+ // Callback function tables from addon to Kodi
+ // Set from Kodi!
+ AddonToKodiFuncTable_Addon* toKodi;
+
+ // Function tables from Kodi to addon
+ // Set from addon header!
+ KodiToAddonFuncTable_Addon* toAddon;
+ } AddonGlobalInterface;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_ADDON_BASE_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/audio_engine.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/audio_engine.h
new file mode 100644
index 0000000..dcb004c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/audio_engine.h
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2005-2019 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.
+ */
+
+#ifndef C_API_AUDIO_ENGINE_H
+#define C_API_AUDIO_ENGINE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ // "C" Definitions, structures and enumerators of audio engine
+ //{{{
+
+ //============================================================================
+ /// @defgroup cpp_kodi_audioengine_Defs_AudioEngineStreamOptions enum AudioEngineStreamOptions
+ /// @ingroup cpp_kodi_audioengine_Defs
+ /// @brief **Bit options to pass to CAEStream**\n
+ /// A bit field of stream options.
+ ///
+ ///
+ /// ------------------------------------------------------------------------
+ ///
+ /// **Usage example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// // Here only as minimal, "format" must be set to wanted types
+ /// kodi::audioengine::AudioEngineFormat format;
+ /// m_audioengine = new kodi::audioengine::CAEStream(format, AUDIO_STREAM_FORCE_RESAMPLE | AUDIO_STREAM_AUTOSTART);
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ typedef enum AudioEngineStreamOptions
+ {
+ /// force resample even if rates match
+ AUDIO_STREAM_FORCE_RESAMPLE = 1 << 0,
+ /// create the stream paused
+ AUDIO_STREAM_PAUSED = 1 << 1,
+ /// autostart the stream when enough data is buffered
+ AUDIO_STREAM_AUTOSTART = 1 << 2,
+ } AudioEngineStreamOptions;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_audioengine_Defs_AudioEngineChannel enum AudioEngineChannel
+ /// @ingroup cpp_kodi_audioengine_Defs
+ /// @brief **The possible channels**\n
+ /// Used to set available or used channels on stream.
+ ///
+ ///
+ /// ------------------------------------------------------------------------
+ ///
+ /// **Usage example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::audioengine::AudioEngineFormat format;
+ /// format.SetChannelLayout(std::vector<AudioEngineChannel>(AUDIOENGINE_CH_FL, AUDIOENGINE_CH_FR));
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ enum AudioEngineChannel
+ {
+ /// Used inside to indicate the end of a list and not for addon use directly.
+ AUDIOENGINE_CH_NULL = -1,
+ /// RAW Audio format
+ AUDIOENGINE_CH_RAW,
+ /// Front left
+ AUDIOENGINE_CH_FL,
+ /// Front right
+ AUDIOENGINE_CH_FR,
+ /// Front center
+ AUDIOENGINE_CH_FC,
+ /// LFE / Subwoofer
+ AUDIOENGINE_CH_LFE,
+ /// Back left
+ AUDIOENGINE_CH_BL,
+ /// Back right
+ AUDIOENGINE_CH_BR,
+ /// Front left over center
+ AUDIOENGINE_CH_FLOC,
+ /// Front right over center
+ AUDIOENGINE_CH_FROC,
+ /// Back center
+ AUDIOENGINE_CH_BC,
+ /// Side left
+ AUDIOENGINE_CH_SL,
+ /// Side right
+ AUDIOENGINE_CH_SR,
+ /// Top front left
+ AUDIOENGINE_CH_TFL,
+ /// Top front right
+ AUDIOENGINE_CH_TFR,
+ /// Top front center
+ AUDIOENGINE_CH_TFC,
+ /// Top center
+ AUDIOENGINE_CH_TC,
+ /// Top back left
+ AUDIOENGINE_CH_TBL,
+ /// Top back right
+ AUDIOENGINE_CH_TBR,
+ /// Top back center
+ AUDIOENGINE_CH_TBC,
+ /// Back left over center
+ AUDIOENGINE_CH_BLOC,
+ /// Back right over center
+ AUDIOENGINE_CH_BROC,
+ /// Maximum possible value, to use e.g. as size inside list
+ AUDIOENGINE_CH_MAX
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_audioengine_Defs_AudioEngineDataFormat enum AudioEngineDataFormat
+ /// @ingroup cpp_kodi_audioengine_Defs
+ /// @brief **Audio sample formats**\n
+ /// The bit layout of the audio data.
+ ///
+ /// LE = Little Endian, BE = Big Endian, NE = Native Endian
+ ///
+ /// For planar sample formats, each audio channel is in a separate data plane,
+ /// and linesize is the buffer size, in bytes, for a single plane. All data
+ /// planes must be the same size. For packed sample formats, only the first
+ /// data plane is used, and samples for each channel are interleaved. In this
+ /// case, linesize is the buffer size, in bytes, for the 1 plane.
+ ///
+ /// @note This is ordered from the worst to best preferred formats
+ ///
+ ///
+ /// ------------------------------------------------------------------------
+ ///
+ /// **Usage example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// kodi::audioengine::AudioEngineFormat format;
+ /// format.SetDataFormat(AUDIOENGINE_FMT_FLOATP);
+ /// ~~~~~~~~~~~~~
+ ///
+ ///@{
+ enum AudioEngineDataFormat
+ {
+ /// To define format as invalid
+ AUDIOENGINE_FMT_INVALID = -1,
+
+ /// Unsigned integer 8 bit
+ AUDIOENGINE_FMT_U8,
+
+ /// Big Endian signed integer 16 bit
+ AUDIOENGINE_FMT_S16BE,
+ /// Little Endian signed integer 16 bit
+ AUDIOENGINE_FMT_S16LE,
+ /// Native Endian signed integer 16 bit
+ AUDIOENGINE_FMT_S16NE,
+
+ /// Big Endian signed integer 32 bit
+ AUDIOENGINE_FMT_S32BE,
+ /// Little Endian signed integer 32 bit
+ AUDIOENGINE_FMT_S32LE,
+ /// Native Endian signed integer 32 bit
+ AUDIOENGINE_FMT_S32NE,
+
+ /// Big Endian signed integer 24 bit (in 4 bytes)
+ AUDIOENGINE_FMT_S24BE4,
+ /// Little Endian signed integer 24 bit (in 4 bytes)
+ AUDIOENGINE_FMT_S24LE4,
+ /// Native Endian signed integer 24 bit (in 4 bytes)
+ AUDIOENGINE_FMT_S24NE4,
+ /// S32 with bits_per_sample < 32
+ AUDIOENGINE_FMT_S24NE4MSB,
+
+ /// Big Endian signed integer 24 bit (3 bytes)
+ AUDIOENGINE_FMT_S24BE3,
+ /// Little Endian signed integer 24 bit (3 bytes)
+ AUDIOENGINE_FMT_S24LE3,
+ /// Native Endian signed integer 24 bit (3 bytes)
+ AUDIOENGINE_FMT_S24NE3,
+
+ /// Double floating point
+ AUDIOENGINE_FMT_DOUBLE,
+ /// Floating point
+ AUDIOENGINE_FMT_FLOAT,
+
+ /// **Bitstream**\n
+ /// RAW Audio format
+ AUDIOENGINE_FMT_RAW,
+
+ /// **Planar format**\n
+ /// Unsigned byte
+ AUDIOENGINE_FMT_U8P,
+ /// **Planar format**\n
+ /// Native Endian signed 16 bit
+ AUDIOENGINE_FMT_S16NEP,
+ /// **Planar format**\n
+ /// Native Endian signed 32 bit
+ AUDIOENGINE_FMT_S32NEP,
+ /// **Planar format**\n
+ /// Native Endian signed integer 24 bit (in 4 bytes)
+ AUDIOENGINE_FMT_S24NE4P,
+ /// **Planar format**\n
+ /// S32 with bits_per_sample < 32
+ AUDIOENGINE_FMT_S24NE4MSBP,
+ /// **Planar format**\n
+ /// Native Endian signed integer 24 bit (in 3 bytes)
+ AUDIOENGINE_FMT_S24NE3P,
+ /// **Planar format**\n
+ /// Double floating point
+ AUDIOENGINE_FMT_DOUBLEP,
+ /// **Planar format**\n
+ /// Floating point
+ AUDIOENGINE_FMT_FLOATP,
+
+ /// Amount of sample formats.
+ AUDIOENGINE_FMT_MAX
+ };
+ ///@}
+ //----------------------------------------------------------------------------
+
+ /*!
+ * @brief Internal API structure which are used for data exchange between
+ * Kodi and addon.
+ */
+ struct AUDIO_ENGINE_FORMAT
+ {
+ /*! The stream's data format (eg, AUDIOENGINE_FMT_S16LE) */
+ enum AudioEngineDataFormat m_dataFormat;
+
+ /*! The stream's sample rate (eg, 48000) */
+ unsigned int m_sampleRate;
+
+ /*! The encoded streams sample rate if a bitstream, otherwise undefined */
+ unsigned int m_encodedRate;
+
+ /*! The amount of used speaker channels */
+ unsigned int m_channelCount;
+
+ /*! The stream's channel layout */
+ enum AudioEngineChannel m_channels[AUDIOENGINE_CH_MAX];
+
+ /*! The number of frames per period */
+ unsigned int m_frames;
+
+ /*! The size of one frame in bytes */
+ unsigned int m_frameSize;
+ };
+
+ /* A stream handle pointer, which is only used internally by the addon stream handle */
+ typedef void AEStreamHandle;
+
+ //}}}
+
+ //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ // "C" Internal interface tables for intercommunications between addon and kodi
+ //{{{
+
+ /*
+ * Function address structure, not need to visible on dev kit doxygen
+ * documentation
+ */
+ typedef struct AddonToKodiFuncTable_kodi_audioengine
+ {
+ AEStreamHandle* (*make_stream)(void* kodiBase,
+ struct AUDIO_ENGINE_FORMAT* format,
+ unsigned int options);
+ void (*free_stream)(void* kodiBase, AEStreamHandle* stream);
+ bool (*get_current_sink_format)(void* kodiBase, struct AUDIO_ENGINE_FORMAT* sink_format);
+
+ // Audio Engine Stream definitions
+ 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,
+ bool hasDownmix,
+ double centerMixLevel);
+ 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);
+ enum AudioEngineDataFormat (*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;
+
+ //}}}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_AUDIO_ENGINE_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h
new file mode 100644
index 0000000..aedcf64
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h
@@ -0,0 +1,322 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_FILESYSTEM_H
+#define C_API_FILESYSTEM_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <time.h>
+
+#ifdef _WIN32 // windows
+#ifndef _SSIZE_T_DEFINED
+typedef intptr_t ssize_t;
+#define _SSIZE_T_DEFINED
+#endif // !_SSIZE_T_DEFINED
+
+// Prevent conflicts with Windows macros where have this names.
+#ifdef CreateDirectory
+#undef CreateDirectory
+#endif // CreateDirectory
+#ifdef DeleteFile
+#undef DeleteFile
+#endif // DeleteFile
+#ifdef RemoveDirectory
+#undef RemoveDirectory
+#endif // RemoveDirectory
+#endif // _WIN32
+
+#ifdef TARGET_POSIX // Linux, Mac, FreeBSD
+#include <sys/types.h>
+#endif // TARGET_POSIX
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ // "C" Definitions, structures and enumerators of filesystem
+ //{{{
+
+ //============================================================================
+ /// @defgroup cpp_kodi_vfs_Defs_OpenFileFlags enum OpenFileFlags
+ /// @ingroup cpp_kodi_vfs_Defs
+ /// @brief **Flags to define way how file becomes opened**\n
+ /// The values can be used together, e.g. <b>`file.Open("myfile", ADDON_READ_TRUNCATED | ADDON_READ_CHUNKED);`</b>
+ ///
+ /// Used on @ref kodi::vfs::CFile::OpenFile().
+ ///
+ ///@{
+ typedef enum OpenFileFlags
+ {
+ /// @brief **0000 0000 0001** :\n
+ /// Indicate that caller can handle truncated reads, where function
+ /// returns before entire buffer has been filled.
+ ADDON_READ_TRUNCATED = 0x01,
+
+ /// @brief **0000 0000 0010** :\n
+ /// Indicate that that caller support read in the minimum defined
+ /// chunk size, this disables internal cache then.
+ ADDON_READ_CHUNKED = 0x02,
+
+ /// @brief **0000 0000 0100** :\n
+ /// Use cache to access this file.
+ ADDON_READ_CACHED = 0x04,
+
+ /// @brief **0000 0000 1000** :\n
+ /// Open without caching. regardless to file type.
+ ADDON_READ_NO_CACHE = 0x08,
+
+ /// @brief **0000 0001 0000** :\n
+ /// Calculate bitrate for file while reading.
+ ADDON_READ_BITRATE = 0x10,
+
+ /// @brief **0000 0010 0000** :\n
+ /// Indicate to the caller we will seek between multiple streams in
+ /// the file frequently.
+ ADDON_READ_MULTI_STREAM = 0x20,
+
+ /// @brief **0000 0100 0000** :\n
+ /// indicate to the caller file is audio and/or video (and e.g. may
+ /// grow).
+ ADDON_READ_AUDIO_VIDEO = 0x40,
+
+ /// @brief **0000 1000 0000** :\n
+ /// Indicate that caller will do write operations before reading.
+ ADDON_READ_AFTER_WRITE = 0x80,
+
+ /// @brief **0001 0000 0000** :\n
+ /// Indicate that caller want to reopen a file if its already open.
+ ADDON_READ_REOPEN = 0x100
+ } OpenFileFlags;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_vfs_Defs_CURLOptiontype enum CURLOptiontype
+ /// @ingroup cpp_kodi_vfs_Defs
+ /// @brief **CURL message types**\n
+ /// Used on kodi::vfs::CFile::CURLAddOption().
+ ///
+ ///@{
+ typedef enum CURLOptiontype
+ {
+ /// @brief Set a general option.
+ ADDON_CURL_OPTION_OPTION,
+
+ /// @brief Set a protocol option.\n
+ ///\n
+ /// The following names for *ADDON_CURL_OPTION_PROTOCOL* are possible:
+ /// | Option name | Description
+ /// |------------------------------------:|:--------------------------------
+ /// | <b>`accept-charset`</b> | Set the "accept-charset" header
+ /// | <b>`acceptencoding or encoding`</b> | Set the "accept-encoding" header
+ /// | <b>`active-remote`</b> | Set the "active-remote" header
+ /// | <b>`auth`</b> | Set the authentication method. Possible values: any, anysafe, digest, ntlm
+ /// | <b>`connection-timeout`</b> | Set the connection timeout in seconds
+ /// | <b>`cookie`</b> | Set the "cookie" header
+ /// | <b>`customrequest`</b> | Set a custom HTTP request like DELETE
+ /// | <b>`noshout`</b> | Set to true if kodi detects a stream as shoutcast by mistake.
+ /// | <b>`postdata`</b> | Set the post body (value needs to be base64 encoded). (Implicitly sets the request to POST)
+ /// | <b>`referer`</b> | Set the "referer" header
+ /// | <b>`user-agent`</b> | Set the "user-agent" header
+ /// | <b>`seekable`</b> | Set the stream seekable. 1: enable, 0: disable
+ /// | <b>`sslcipherlist`</b> | Set list of accepted SSL ciphers.
+ ///
+ ADDON_CURL_OPTION_PROTOCOL,
+
+ /// @brief Set User and password
+ ADDON_CURL_OPTION_CREDENTIALS,
+
+ /// @brief Add a Header
+ ADDON_CURL_OPTION_HEADER
+ } CURLOptiontype;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_vfs_Defs_FilePropertyTypes enum FilePropertyTypes
+ /// @ingroup cpp_kodi_vfs_Defs
+ /// @brief **File property types**\n
+ /// Mostly to read internet sources.
+ ///
+ /// Used on kodi::vfs::CFile::GetPropertyValue() and kodi::vfs::CFile::GetPropertyValues().
+ ///
+ ///@{
+ typedef enum FilePropertyTypes
+ {
+ /// @brief Get protocol response line.
+ ADDON_FILE_PROPERTY_RESPONSE_PROTOCOL,
+ /// @brief Get a response header.
+ ADDON_FILE_PROPERTY_RESPONSE_HEADER,
+ /// @brief Get file content type.
+ ADDON_FILE_PROPERTY_CONTENT_TYPE,
+ /// @brief Get file content charset.
+ ADDON_FILE_PROPERTY_CONTENT_CHARSET,
+ /// @brief Get file mime type.
+ ADDON_FILE_PROPERTY_MIME_TYPE,
+ /// @brief Get file effective URL (last one if redirected).
+ ADDON_FILE_PROPERTY_EFFECTIVE_URL
+ } FilePropertyTypes;
+ ///@}
+ //----------------------------------------------------------------------------
+
+ //}}}
+
+ //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ // "C" Internal interface tables for intercommunications between addon and kodi
+ //{{{
+
+ struct KODI_HTTP_HEADER
+ {
+ void* handle;
+
+ char* (*get_value)(void* kodiBase, void* handle, const char* param);
+ char** (*get_values)(void* kodiBase, void* handle, const char* param, int* length);
+ char* (*get_header)(void* kodiBase, void* handle);
+ char* (*get_mime_type)(void* kodiBase, void* handle);
+ char* (*get_charset)(void* kodiBase, void* handle);
+ char* (*get_proto_line)(void* kodiBase, void* handle);
+ };
+
+ struct STAT_STRUCTURE
+ {
+ /// ID of device containing file
+ uint32_t deviceId;
+ /// Total size, in bytes
+ uint64_t size;
+ /// Time of last access
+ time_t accessTime;
+ /// Time of last modification
+ time_t modificationTime;
+ /// Time of last status change
+ time_t statusTime;
+ /// The stat url is a directory
+ bool isDirectory;
+ /// The stat url is a symbolic link
+ bool isSymLink;
+ /// The stat url is block special
+ bool isBlock;
+ /// The stat url is character special
+ bool isCharacter;
+ /// The stat url is FIFO special
+ bool isFifo;
+ /// The stat url is regular
+ bool isRegular;
+ /// The stat url is socket
+ bool isSocket;
+ /// The file serial number, which distinguishes this file from all other files on the same
+ /// device.
+ uint64_t fileSerialNumber;
+ };
+
+ struct VFS_CACHE_STATUS_DATA
+ {
+ uint64_t forward;
+ uint32_t maxrate;
+ uint32_t currate;
+ uint32_t lowrate;
+ };
+
+ struct VFSProperty
+ {
+ char* name;
+ char* val;
+ };
+
+ struct VFSDirEntry
+ {
+ char* label; //!< item label
+ char* title; //!< item title
+ char* path; //!< item path
+ unsigned int num_props; //!< Number of properties attached to item
+ struct VFSProperty* properties; //!< Properties
+ time_t date_time; //!< file creation date & time
+ bool folder; //!< Item is a folder
+ uint64_t size; //!< Size of file represented by item
+ };
+
+ typedef struct AddonToKodiFuncTable_kodi_filesystem
+ {
+ bool (*can_open_directory)(void* kodiBase, const char* url);
+ bool (*create_directory)(void* kodiBase, const char* path);
+ bool (*remove_directory)(void* kodiBase, const char* path);
+ bool (*directory_exists)(void* kodiBase, const char* path);
+ bool (*get_directory)(void* kodiBase,
+ const char* path,
+ const char* mask,
+ struct VFSDirEntry** items,
+ unsigned int* num_items);
+ void (*free_directory)(void* kodiBase, struct VFSDirEntry* items, unsigned int num_items);
+
+ bool (*file_exists)(void* kodiBase, const char* filename, bool useCache);
+ bool (*stat_file)(void* kodiBase, const char* filename, struct STAT_STRUCTURE* buffer);
+ bool (*delete_file)(void* kodiBase, const char* filename);
+ bool (*rename_file)(void* kodiBase, const char* filename, const char* newFileName);
+ bool (*copy_file)(void* kodiBase, const char* filename, const char* dest);
+
+ char* (*get_file_md5)(void* kodiBase, const char* filename);
+ char* (*get_cache_thumb_name)(void* kodiBase, const char* filename);
+ char* (*make_legal_filename)(void* kodiBase, const char* filename);
+ char* (*make_legal_path)(void* kodiBase, const char* path);
+ char* (*translate_special_protocol)(void* kodiBase, const char* strSource);
+ bool (*is_internet_stream)(void* kodiBase, const char* path, bool strictCheck);
+ bool (*is_on_lan)(void* kodiBase, const char* path);
+ bool (*is_remote)(void* kodiBase, const char* path);
+ bool (*is_local)(void* kodiBase, const char* path);
+ bool (*is_url)(void* kodiBase, const char* path);
+ bool (*get_http_header)(void* kodiBase, const char* url, struct KODI_HTTP_HEADER* headers);
+ bool (*get_mime_type)(void* kodiBase, const char* url, char** content, const char* useragent);
+ bool (*get_content_type)(void* kodiBase,
+ const char* url,
+ char** content,
+ const char* useragent);
+ bool (*get_cookies)(void* kodiBase, const char* url, char** cookies);
+ bool (*http_header_create)(void* kodiBase, struct KODI_HTTP_HEADER* headers);
+ void (*http_header_free)(void* kodiBase, struct KODI_HTTP_HEADER* headers);
+
+ void* (*open_file)(void* kodiBase, const char* filename, unsigned int flags);
+ void* (*open_file_for_write)(void* kodiBase, const char* filename, bool overwrite);
+ ssize_t (*read_file)(void* kodiBase, void* file, void* ptr, size_t size);
+ bool (*read_file_string)(void* kodiBase, void* file, char* szLine, int iLineLength);
+ ssize_t (*write_file)(void* kodiBase, void* file, const void* ptr, size_t size);
+ void (*flush_file)(void* kodiBase, void* file);
+ int64_t (*seek_file)(void* kodiBase, void* file, int64_t position, int whence);
+ int (*truncate_file)(void* kodiBase, void* file, int64_t size);
+ int64_t (*get_file_position)(void* kodiBase, void* file);
+ int64_t (*get_file_length)(void* kodiBase, void* file);
+ 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);
+ bool (*io_control_get_seek_possible)(void* kodiBase, void* file);
+ bool (*io_control_get_cache_status)(void* kodiBase,
+ void* file,
+ struct VFS_CACHE_STATUS_DATA* status);
+ bool (*io_control_set_cache_rate)(void* kodiBase, void* file, uint32_t rate);
+ bool (*io_control_set_retry)(void* kodiBase, void* file, bool retry);
+ char** (*get_property_values)(
+ void* kodiBase, void* file, int type, const char* name, int* numValues);
+
+ void* (*curl_create)(void* kodiBase, const char* url);
+ bool (*curl_add_option)(
+ void* kodiBase, void* file, int type, const char* name, const char* value);
+ bool (*curl_open)(void* kodiBase, void* file, unsigned int flags);
+
+ bool (*get_disk_space)(
+ void* kodiBase, const char* path, uint64_t* capacity, uint64_t* free, uint64_t* available);
+ bool (*remove_directory_recursive)(void* kodiBase, const char* path);
+ } AddonToKodiFuncTable_kodi_filesystem;
+
+ //}}}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_FILESYSTEM_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/general.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/general.h
new file mode 100644
index 0000000..2188db9
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/general.h
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_GENERAL_H
+#define C_API_GENERAL_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// \ingroup cpp_kodi_Defs
+ /// @brief For kodi::CurrentKeyboardLayout used defines
+ ///
+ typedef enum StdKbButtons
+ {
+ /// The quantity of buttons per row on Kodi's standard keyboard
+ STD_KB_BUTTONS_PER_ROW = 20,
+ /// The quantity of rows on Kodi's standard keyboard
+ STD_KB_BUTTONS_MAX_ROWS = 4,
+ /// Keyboard layout type, this for initial standard
+ STD_KB_MODIFIER_KEY_NONE = 0x00,
+ /// Keyboard layout type, this for shift controlled layout (uppercase)
+ STD_KB_MODIFIER_KEY_SHIFT = 0x01,
+ /// Keyboard layout type, this to show symbols
+ STD_KB_MODIFIER_KEY_SYMBOL = 0x02
+ } StdKbButtons;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// \ingroup cpp_kodi_Defs
+ /// @brief For kodi::QueueNotification() used message types
+ ///
+ typedef enum QueueMsg
+ {
+ /// Show info notification message
+ QUEUE_INFO,
+ /// Show warning notification message
+ QUEUE_WARNING,
+ /// Show error notification message
+ QUEUE_ERROR,
+ /// Show with own given image and parts if set on values
+ QUEUE_OWN_STYLE
+ } QueueMsg;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// \ingroup cpp_kodi_Defs
+ /// @brief Format codes to get string from them.
+ ///
+ /// Used on kodi::GetLanguage().
+ ///
+ typedef enum LangFormats
+ {
+ /// two letter code as defined in ISO 639-1
+ LANG_FMT_ISO_639_1,
+ /// three letter code as defined in ISO 639-2/T or ISO 639-2/B
+ LANG_FMT_ISO_639_2,
+ /// full language name in English
+ LANG_FMT_ENGLISH_NAME
+ } LangFormats;
+ //----------------------------------------------------------------------------
+
+ /*
+ * For interface between add-on and kodi.
+ *
+ * This structure defines the addresses of functions stored inside Kodi which
+ * are then available for the add-on to call
+ *
+ * All function pointers there are used by the C++ interface functions below.
+ * You find the set of them on xbmc/addons/interfaces/General.cpp
+ *
+ * Note: For add-on development itself this is not needed
+ */
+ typedef struct AddonKeyboardKeyTable
+ {
+ char* keys[STD_KB_BUTTONS_MAX_ROWS][STD_KB_BUTTONS_PER_ROW];
+ } AddonKeyboardKeyTable;
+ typedef struct AddonToKodiFuncTable_kodi
+ {
+ char* (*unknown_to_utf8)(void* kodiBase, const char* source, bool* ret, bool failOnBadChar);
+ char* (*get_language)(void* kodiBase, int format, bool region);
+ bool (*queue_notification)(void* kodiBase,
+ int type,
+ const char* header,
+ const char* message,
+ const char* imageFile,
+ unsigned int displayTime,
+ bool withSound,
+ unsigned int messageTime);
+ void (*get_md5)(void* kodiBase, const char* text, char* md5);
+ char* (*get_region)(void* kodiBase, const char* id);
+ void (*get_free_mem)(void* kodiBase, long* free, long* total, bool as_bytes);
+ int (*get_global_idle_time)(void* kodiBase);
+ bool (*is_addon_avilable)(void* kodiBase, const char* id, char** version, bool* enabled);
+ void (*kodi_version)(void* kodiBase,
+ char** compile_name,
+ int* major,
+ int* minor,
+ char** revision,
+ char** tag,
+ char** tagversion);
+ char* (*get_current_skin_id)(void* kodiBase);
+ bool (*get_keyboard_layout)(void* kodiBase,
+ char** layout_name,
+ int modifier_key,
+ struct AddonKeyboardKeyTable* layout);
+ bool (*change_keyboard_layout)(void* kodiBase, char** layout_name);
+ } AddonToKodiFuncTable_kodi;
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GENERAL_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/CMakeLists.txt
new file mode 100644
index 0000000..0971ed5
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ definitions.h
+ general.h
+ list_item.h
+ window.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_gui)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/CMakeLists.txt
new file mode 100644
index 0000000..853eb2d
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ button.h
+ edit.h
+ fade_label.h
+ image.h
+ label.h
+ progress.h
+ radio_button.h
+ rendering.h
+ settings_slider.h
+ slider.h
+ spin.h
+ text_box.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_gui_controls)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/button.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/button.h
new file mode 100644
index 0000000..46de262
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/button.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_BUTTON_H
+#define C_API_GUI_CONTROLS_BUTTON_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_button
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_enabled)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
+ void (*set_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ char* (*get_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_label2)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ char* (*get_label2)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_control_button;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_BUTTON_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/edit.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/edit.h
new file mode 100644
index 0000000..571c7ce
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/edit.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_EDIT_H
+#define C_API_GUI_CONTROLS_EDIT_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit_Defs
+ /// @{
+ /// @anchor AddonGUIInputType
+ /// @brief Text input types used on kodi::gui::controls::CEdit
+ enum AddonGUIInputType
+ {
+ /// Text inside edit control only readable
+ ADDON_INPUT_TYPE_READONLY = -1,
+ /// Normal text entries
+ ADDON_INPUT_TYPE_TEXT = 0,
+ /// To use on edit control only numeric numbers
+ ADDON_INPUT_TYPE_NUMBER,
+ /// To insert seconds
+ ADDON_INPUT_TYPE_SECONDS,
+ /// To insert time
+ ADDON_INPUT_TYPE_TIME,
+ /// To insert a date
+ ADDON_INPUT_TYPE_DATE,
+ /// Used for write in IP addresses
+ ADDON_INPUT_TYPE_IPADDRESS,
+ /// Text field used as password entry field with not visible text
+ ADDON_INPUT_TYPE_PASSWORD,
+ /// Text field used as password entry field with not visible text but
+ /// returned as MD5 value
+ ADDON_INPUT_TYPE_PASSWORD_MD5,
+ /// Use text field for search purpose
+ ADDON_INPUT_TYPE_SEARCH,
+ /// Text field as filter
+ ADDON_INPUT_TYPE_FILTER,
+ ///
+ ADDON_INPUT_TYPE_PASSWORD_NUMBER_VERIFY_NEW
+ };
+ /// @}
+ //----------------------------------------------------------------------------
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_edit
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_enabled)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
+ void (*set_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ char* (*get_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_text)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ char* (*get_text)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_cursor_position)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ unsigned int position);
+ unsigned int (*get_cursor_position)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_input_type)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int type,
+ const char* heading);
+ } AddonToKodiFuncTable_kodi_gui_control_edit;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_EDIT_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/fade_label.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/fade_label.h
new file mode 100644
index 0000000..dab4574
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/fade_label.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_FADE_LABEL_H
+#define C_API_GUI_CONTROLS_FADE_LABEL_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_fade_label
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*add_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ char* (*get_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_scrolling)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool scroll);
+ void (*reset)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_control_fade_label;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_FADE_LABEL_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/image.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/image.h
new file mode 100644
index 0000000..257dd67
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/image.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_IMAGE_H
+#define C_API_GUI_CONTROLS_IMAGE_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_image
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_filename)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* filename,
+ bool use_cache);
+ void (*set_color_diffuse)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ uint32_t color_diffuse);
+ } AddonToKodiFuncTable_kodi_gui_control_image;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_IMAGE_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/label.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/label.h
new file mode 100644
index 0000000..92af25c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/label.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_LABEL_H
+#define C_API_GUI_CONTROLS_LABEL_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_label
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ char* (*get_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_control_label;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_LABEL_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/progress.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/progress.h
new file mode 100644
index 0000000..4f211fd
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/progress.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_PROGRESS_H
+#define C_API_GUI_CONTROLS_PROGRESS_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_progress
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_percentage)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float percent);
+ float (*get_percentage)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_control_progress;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_PROGRESS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/radio_button.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/radio_button.h
new file mode 100644
index 0000000..d652e67
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/radio_button.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_RADIO_BUTTON_H
+#define C_API_GUI_CONTROLS_RADIO_BUTTON_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_radio_button
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_enabled)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
+ void (*set_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ char* (*get_label)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_selected)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool selected);
+ bool (*is_selected)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_control_radio_button;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_RADIO_BUTTON_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/rendering.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/rendering.h
new file mode 100644
index 0000000..792a8d6
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/rendering.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_RENDERING_H
+#define C_API_GUI_CONTROLS_RENDERING_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_rendering
+ {
+ void (*set_callbacks)(
+ KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ KODI_GUI_CLIENT_HANDLE clienthandle,
+ bool (*createCB)(KODI_GUI_CLIENT_HANDLE, int, int, int, int, ADDON_HARDWARE_CONTEXT),
+ void (*renderCB)(KODI_GUI_CLIENT_HANDLE),
+ void (*stopCB)(KODI_GUI_CLIENT_HANDLE),
+ bool (*dirtyCB)(KODI_GUI_CLIENT_HANDLE));
+ void (*destroy)(void* kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_control_rendering;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_RENDERING_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/settings_slider.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/settings_slider.h
new file mode 100644
index 0000000..4299252
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/settings_slider.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_SETTINGS_SLIDER_H
+#define C_API_GUI_CONTROLS_SETTINGS_SLIDER_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_settings_slider
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_enabled)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
+ void (*set_text)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ void (*reset)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_int_range)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int start, int end);
+ void (*set_int_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int value);
+ int (*get_int_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_int_interval)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int interval);
+ void (*set_percentage)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float percent);
+ float (*get_percentage)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_float_range)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end);
+ void (*set_float_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float value);
+ float (*get_float_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_float_interval)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval);
+ } AddonToKodiFuncTable_kodi_gui_control_settings_slider;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_SETTINGS_SLIDER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/slider.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/slider.h
new file mode 100644
index 0000000..67c6c2f
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/slider.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_SLIDER_H
+#define C_API_GUI_CONTROLS_SLIDER_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_slider
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_enabled)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
+ void (*reset)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ char* (*get_description)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_int_range)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int start, int end);
+ void (*set_int_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int value);
+ int (*get_int_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_int_interval)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int interval);
+ void (*set_percentage)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float percent);
+ float (*get_percentage)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_float_range)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end);
+ void (*set_float_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float value);
+ float (*get_float_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_float_interval)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval);
+ } AddonToKodiFuncTable_kodi_gui_control_slider;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_SLIDER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/spin.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/spin.h
new file mode 100644
index 0000000..0373636
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/spin.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_SPIN_H
+#define C_API_GUI_CONTROLS_SPIN_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_spin
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*set_enabled)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
+ void (*set_text)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ void (*reset)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_type)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int type);
+ void (*add_string_label)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label,
+ const char* value);
+ void (*set_string_value)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* value);
+ char* (*get_string_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*add_int_label)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label,
+ int value);
+ void (*set_int_range)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int start, int end);
+ void (*set_int_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int value);
+ int (*get_int_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_float_range)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end);
+ void (*set_float_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float value);
+ float (*get_float_value)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_float_interval)(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval);
+ } AddonToKodiFuncTable_kodi_gui_control_spin;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_SPIN_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/text_box.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/text_box.h
new file mode 100644
index 0000000..333689e
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/text_box.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_CONTROLS_TEXT_BOX_H
+#define C_API_GUI_CONTROLS_TEXT_BOX_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_control_text_box
+ {
+ void (*set_visible)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ void (*reset)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*set_text)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ char* (*get_text)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ void (*scroll)(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, unsigned int scroll);
+ void (*set_auto_scrolling)(
+ KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int delay, int time, int repeat);
+ } AddonToKodiFuncTable_kodi_gui_control_text_box;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_CONTROLS_TEXT_BOX_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/definitions.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/definitions.h
new file mode 100644
index 0000000..75fa721
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/definitions.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_GUI_DEFINITIONS_H
+#define C_API_GUI_DEFINITIONS_H
+
+#include "../addon_base.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef void* KODI_GUI_HANDLE;
+ typedef void* KODI_GUI_CLIENT_HANDLE;
+ typedef void* KODI_GUI_CONTROL_HANDLE;
+ typedef void* KODI_GUI_LISTITEM_HANDLE;
+ typedef void* KODI_GUI_WINDOW_HANDLE;
+
+ typedef struct AddonToKodiFuncTable_kodi_gui
+ {
+ struct AddonToKodiFuncTable_kodi_gui_general* general;
+ struct AddonToKodiFuncTable_kodi_gui_control_button* control_button;
+ struct AddonToKodiFuncTable_kodi_gui_control_edit* control_edit;
+ struct AddonToKodiFuncTable_kodi_gui_control_fade_label* control_fade_label;
+ struct AddonToKodiFuncTable_kodi_gui_control_label* control_label;
+ struct AddonToKodiFuncTable_kodi_gui_control_image* control_image;
+ struct AddonToKodiFuncTable_kodi_gui_control_progress* control_progress;
+ struct AddonToKodiFuncTable_kodi_gui_control_radio_button* control_radio_button;
+ struct AddonToKodiFuncTable_kodi_gui_control_rendering* control_rendering;
+ struct AddonToKodiFuncTable_kodi_gui_control_settings_slider* control_settings_slider;
+ struct AddonToKodiFuncTable_kodi_gui_control_slider* control_slider;
+ struct AddonToKodiFuncTable_kodi_gui_control_spin* control_spin;
+ struct AddonToKodiFuncTable_kodi_gui_control_text_box* control_text_box;
+ KODI_HANDLE control_dummy1;
+ KODI_HANDLE control_dummy2;
+ KODI_HANDLE control_dummy3;
+ KODI_HANDLE control_dummy4;
+ KODI_HANDLE control_dummy5;
+ KODI_HANDLE control_dummy6;
+ KODI_HANDLE control_dummy7;
+ KODI_HANDLE control_dummy8;
+ KODI_HANDLE control_dummy9;
+ KODI_HANDLE control_dummy10; /* This and above used to add new controls */
+ struct AddonToKodiFuncTable_kodi_gui_dialogContextMenu* dialogContextMenu;
+ struct AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress* dialogExtendedProgress;
+ struct AddonToKodiFuncTable_kodi_gui_dialogFileBrowser* dialogFileBrowser;
+ struct AddonToKodiFuncTable_kodi_gui_dialogKeyboard* dialogKeyboard;
+ struct AddonToKodiFuncTable_kodi_gui_dialogNumeric* dialogNumeric;
+ struct AddonToKodiFuncTable_kodi_gui_dialogOK* dialogOK;
+ struct AddonToKodiFuncTable_kodi_gui_dialogProgress* dialogProgress;
+ struct AddonToKodiFuncTable_kodi_gui_dialogSelect* dialogSelect;
+ struct AddonToKodiFuncTable_kodi_gui_dialogTextViewer* dialogTextViewer;
+ struct AddonToKodiFuncTable_kodi_gui_dialogYesNo* dialogYesNo;
+ KODI_HANDLE dialog_dummy1;
+ KODI_HANDLE dialog_dummy2;
+ KODI_HANDLE dialog_dummy3;
+ KODI_HANDLE dialog_dummy4;
+ KODI_HANDLE dialog_dummy5;
+ KODI_HANDLE dialog_dummy6;
+ KODI_HANDLE dialog_dummy7;
+ KODI_HANDLE dialog_dummy8;
+ KODI_HANDLE dialog_dummy9;
+ KODI_HANDLE dialog_dummy10; /* This and above used to add new dialogs */
+ struct AddonToKodiFuncTable_kodi_gui_listItem* listItem;
+ struct AddonToKodiFuncTable_kodi_gui_window* window;
+ } AddonToKodiFuncTable_kodi_gui;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DEFINITIONS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/CMakeLists.txt
new file mode 100644
index 0000000..91caa50
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ context_menu.h
+ extended_progress.h
+ filebrowser.h
+ keyboard.h
+ numeric.h
+ ok.h
+ progress.h
+ select.h
+ text_viewer.h
+ yes_no.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_gui_dialogs)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/context_menu.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/context_menu.h
new file mode 100644
index 0000000..130d831
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/context_menu.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_CONTEXT_MENU_H
+#define C_API_GUI_DIALOGS_CONTEXT_MENU_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogContextMenu
+ {
+ int (*open)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entries[],
+ unsigned int size);
+ } AddonToKodiFuncTable_kodi_gui_dialogContextMenu;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_CONTEXT_MENU_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/extended_progress.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/extended_progress.h
new file mode 100644
index 0000000..0992d5c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/extended_progress.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_EXTENDED_PROGRESS_H
+#define C_API_GUI_DIALOGS_EXTENDED_PROGRESS_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress
+ {
+ KODI_GUI_HANDLE (*new_dialog)(KODI_HANDLE kodiBase, const char* title);
+ void (*delete_dialog)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ char* (*get_title)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*set_title)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, const char* title);
+ char* (*get_text)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*set_text)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, const char* text);
+ bool (*is_finished)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*mark_finished)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ float (*get_percentage)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*set_percentage)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, float percentage);
+ void (*set_progress)(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ int currentItem,
+ int itemCount);
+ } AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_EXTENDED_PROGRESS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/filebrowser.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/filebrowser.h
new file mode 100644
index 0000000..ef3945b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/filebrowser.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_FILEBROWSER_H
+#define C_API_GUI_DIALOGS_FILEBROWSER_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogFileBrowser
+ {
+ bool (*show_and_get_directory)(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ const char* path_in,
+ char** path_out,
+ bool writeOnly);
+ bool (*show_and_get_file)(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* mask,
+ const char* heading,
+ const char* path_in,
+ char** path_out,
+ bool use_thumbs,
+ bool use_file_directories);
+ bool (*show_and_get_file_from_dir)(KODI_HANDLE kodiBase,
+ const char* directory,
+ const char* mask,
+ const char* heading,
+ const char* path_in,
+ char** path_out,
+ bool use_thumbs,
+ bool use_file_directories,
+ bool singleList);
+ bool (*show_and_get_file_list)(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* mask,
+ const char* heading,
+ char*** file_list,
+ unsigned int* entries,
+ bool use_thumbs,
+ bool use_file_directories);
+ bool (*show_and_get_source)(KODI_HANDLE kodiBase,
+ const char* path_in,
+ char** path_out,
+ bool allow_network_shares,
+ const char* additional_share,
+ const char* type);
+ bool (*show_and_get_image)(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ const char* path_in,
+ char** path_out);
+ bool (*show_and_get_image_list)(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ char*** file_list,
+ unsigned int* entries);
+ void (*clear_file_list)(KODI_HANDLE kodiBase, char*** file_list, unsigned int entries);
+ } AddonToKodiFuncTable_kodi_gui_dialogFileBrowser;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_FILEBROWSER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/keyboard.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/keyboard.h
new file mode 100644
index 0000000..f84dc20
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/keyboard.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_KEYBOARD_H
+#define C_API_GUI_DIALOGS_KEYBOARD_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogKeyboard
+ {
+ bool (*show_and_get_input_with_head)(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ const char* heading,
+ bool allow_empty_result,
+ bool hiddenInput,
+ unsigned int auto_close_ms);
+ bool (*show_and_get_input)(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ bool allow_empty_result,
+ unsigned int auto_close_ms);
+ bool (*show_and_get_new_password_with_head)(KODI_HANDLE kodiBase,
+ const char* password_in,
+ char** password_out,
+ const char* heading,
+ bool allow_empty_result,
+ unsigned int auto_close_ms);
+ bool (*show_and_get_new_password)(KODI_HANDLE kodiBase,
+ const char* password_in,
+ char** password_out,
+ unsigned int auto_close_ms);
+ bool (*show_and_verify_new_password_with_head)(KODI_HANDLE kodiBase,
+ char** password_out,
+ const char* heading,
+ bool allow_empty_result,
+ unsigned int auto_close_ms);
+ bool (*show_and_verify_new_password)(KODI_HANDLE kodiBase,
+ char** password_out,
+ unsigned int auto_close_ms);
+ int (*show_and_verify_password)(KODI_HANDLE kodiBase,
+ const char* password_in,
+ char** password_out,
+ const char* heading,
+ int retries,
+ unsigned int auto_close_ms);
+ bool (*show_and_get_filter)(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ bool searching,
+ unsigned int auto_close_ms);
+ bool (*send_text_to_active_keyboard)(KODI_HANDLE kodiBase,
+ const char* text,
+ bool close_keyboard);
+ bool (*is_keyboard_activated)(KODI_HANDLE kodiBase);
+ } AddonToKodiFuncTable_kodi_gui_dialogKeyboard;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_KEYBOARD_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/numeric.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/numeric.h
new file mode 100644
index 0000000..08aaf25
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/numeric.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_NUMERIC_H
+#define C_API_GUI_DIALOGS_NUMERIC_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogNumeric
+ {
+ bool (*show_and_verify_new_password)(KODI_HANDLE kodiBase, char** password);
+ int (*show_and_verify_password)(KODI_HANDLE kodiBase,
+ const char* password,
+ const char* heading,
+ int retries);
+ bool (*show_and_verify_input)(KODI_HANDLE kodiBase,
+ const char* verify_in,
+ char** verify_out,
+ const char* heading,
+ bool verify_input);
+ bool (*show_and_get_time)(KODI_HANDLE kodiBase, struct tm* time, const char* heading);
+ bool (*show_and_get_date)(KODI_HANDLE kodiBase, struct tm* date, const char* heading);
+ bool (*show_and_get_ip_address)(KODI_HANDLE kodiBase,
+ const char* ip_address_in,
+ char** ip_address_out,
+ const char* heading);
+ bool (*show_and_get_number)(KODI_HANDLE kodiBase,
+ const char* input_in,
+ char** input_out,
+ const char* heading,
+ unsigned int auto_close_ms);
+ bool (*show_and_get_seconds)(KODI_HANDLE kodiBase,
+ const char* time_in,
+ char** time_out,
+ const char* heading);
+ } AddonToKodiFuncTable_kodi_gui_dialogNumeric;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_NUMERIC_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/ok.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/ok.h
new file mode 100644
index 0000000..45fe0fc
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/ok.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_OK_H
+#define C_API_GUI_DIALOGS_OK_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogOK
+ {
+ void (*show_and_get_input_single_text)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* text);
+ void (*show_and_get_input_line_text)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* line0,
+ const char* line1,
+ const char* line2);
+ } AddonToKodiFuncTable_kodi_gui_dialogOK;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_OK_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/progress.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/progress.h
new file mode 100644
index 0000000..60a003a
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/progress.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_PROGRESS_H
+#define C_API_GUI_DIALOGS_PROGRESS_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogProgress
+ {
+ KODI_GUI_HANDLE (*new_dialog)(KODI_HANDLE kodiBase);
+ void (*delete_dialog)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*open)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*set_heading)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, const char* heading);
+ void (*set_line)(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ unsigned int lineNo,
+ const char* line);
+ void (*set_can_cancel)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, bool canCancel);
+ bool (*is_canceled)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*set_percentage)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, int percentage);
+ int (*get_percentage)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ void (*show_progress_bar)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, bool pnOff);
+ void (*set_progress_max)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, int max);
+ void (*set_progress_advance)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, int nSteps);
+ bool (*abort)(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_dialogProgress;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_PROGRESS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/select.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/select.h
new file mode 100644
index 0000000..79635d7
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/select.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_SELECT_H
+#define C_API_GUI_DIALOGS_SELECT_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogSelect
+ {
+ int (*open)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entries[],
+ unsigned int size,
+ int selected,
+ unsigned int autoclose);
+ bool (*open_multi_select)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entryIDs[],
+ const char* entryNames[],
+ bool entriesSelected[],
+ unsigned int size,
+ unsigned int autoclose);
+ } AddonToKodiFuncTable_kodi_gui_dialogSelect;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_SELECT_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/text_viewer.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/text_viewer.h
new file mode 100644
index 0000000..4a1cfe6
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/text_viewer.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_TEXT_VIEWER_H
+#define C_API_GUI_DIALOGS_TEXT_VIEWER_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogTextViewer
+ {
+ void (*open)(KODI_HANDLE kodiBase, const char* heading, const char* text);
+ } AddonToKodiFuncTable_kodi_gui_dialogTextViewer;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_TEXT_VIEWER_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/yes_no.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/yes_no.h
new file mode 100644
index 0000000..8558acb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/yes_no.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_DIALOGS_YES_NO_H
+#define C_API_GUI_DIALOGS_YES_NO_H
+
+#include "../definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_dialogYesNo
+ {
+ bool (*show_and_get_input_single_text)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* text,
+ bool* canceled,
+ const char* noLabel,
+ const char* yesLabel);
+ bool (*show_and_get_input_line_text)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* line0,
+ const char* line1,
+ const char* line2,
+ const char* noLabel,
+ const char* yesLabel);
+ bool (*show_and_get_input_line_button_text)(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* line0,
+ const char* line1,
+ const char* line2,
+ bool* canceled,
+ const char* noLabel,
+ const char* yesLabel);
+ } AddonToKodiFuncTable_kodi_gui_dialogYesNo;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_DIALOGS_YES_NO_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/general.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/general.h
new file mode 100644
index 0000000..77e43c5
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/general.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_GENERAL_H
+#define C_API_GUI_GENERAL_H
+
+#include "definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ //==============================================================================
+ /// @ingroup cpp_kodi_gui_general
+ /// @brief **Adjust refresh rate enum**\n
+ /// Used to get the Adjust refresh rate status info.
+ ///
+ enum AdjustRefreshRateStatus
+ {
+ ADJUST_REFRESHRATE_STATUS_OFF = 0,
+ ADJUST_REFRESHRATE_STATUS_ALWAYS,
+ ADJUST_REFRESHRATE_STATUS_ON_STARTSTOP,
+ ADJUST_REFRESHRATE_STATUS_ON_START,
+ };
+ //------------------------------------------------------------------------------
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_general
+ {
+ void (*lock)();
+ void (*unlock)();
+ int (*get_screen_height)(KODI_HANDLE kodiBase);
+ int (*get_screen_width)(KODI_HANDLE kodiBase);
+ int (*get_video_resolution)(KODI_HANDLE kodiBase);
+ int (*get_current_window_dialog_id)(KODI_HANDLE kodiBase);
+ int (*get_current_window_id)(KODI_HANDLE kodiBase);
+ ADDON_HARDWARE_CONTEXT (*get_hw_context)(KODI_HANDLE kodiBase);
+ AdjustRefreshRateStatus (*get_adjust_refresh_rate_status)(KODI_HANDLE kodiBase);
+ } AddonToKodiFuncTable_kodi_gui_general;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_GENERAL_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/CMakeLists.txt
new file mode 100644
index 0000000..eb7dde0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ action_ids.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_gui_input)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/action_ids.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/action_ids.h
new file mode 100644
index 0000000..5d62587
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/action_ids.h
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_ACTION_IDS_H
+#define C_API_GUI_ACTION_IDS_H
+
+/// @defgroup cpp_kodi_gui_Defs_action_ids enum ADDON_ACTION
+/// @ingroup cpp_kodi_gui_Defs
+/// @brief **Action Id's**\n
+/// Actions that we have defined.
+///
+///@{
+enum ADDON_ACTION
+{
+ /// @ingroup cpp_kodi_gui_key_action_ids
+ ///@{
+
+ /// @brief <b>`0 `</b>: None.
+ ADDON_ACTION_NONE = 0,
+
+ /// @brief <b>`1 `</b>: Move left.
+ ADDON_ACTION_MOVE_LEFT = 1,
+
+ /// @brief <b>`2 `</b>: Move right.
+ ADDON_ACTION_MOVE_RIGHT = 2,
+
+ /// @brief <b>`3 `</b>: Move up.
+ ADDON_ACTION_MOVE_UP = 3,
+
+ /// @brief <b>`4 `</b>: Move down.
+ ADDON_ACTION_MOVE_DOWN = 4,
+
+ /// @brief <b>`5 `</b>: Page up.
+ ADDON_ACTION_PAGE_UP = 5,
+
+ /// @brief <b>`6 `</b>: Page down.
+ ADDON_ACTION_PAGE_DOWN = 6,
+
+ /// @brief <b>`7 `</b>: Select item.
+ ADDON_ACTION_SELECT_ITEM = 7,
+
+ /// @brief <b>`8 `</b>: Highlight item.
+ ADDON_ACTION_HIGHLIGHT_ITEM = 8,
+
+ /// @brief <b>`9 `</b>: Parent directory.
+ ADDON_ACTION_PARENT_DIR = 9,
+
+ /// @brief <b>`10 `</b>: Previous menu.
+ ADDON_ACTION_PREVIOUS_MENU = 10,
+
+ /// @brief <b>`11 `</b>: Show info.
+ ADDON_ACTION_SHOW_INFO = 11,
+
+ /// @brief <b>`12 `</b>: Pause.
+ ADDON_ACTION_PAUSE = 12,
+
+ /// @brief <b>`13 `</b>: Stop.
+ ADDON_ACTION_STOP = 13,
+
+ /// @brief <b>`14 `</b>: Next item.
+ ADDON_ACTION_NEXT_ITEM = 14,
+
+ /// @brief <b>`15 `</b>: Previous item.
+ ADDON_ACTION_PREV_ITEM = 15,
+
+ /// @brief <b>`16 `</b>: Can be used to specify specific action in a window, Playback control is handled in ADDON_ACTION_PLAYER_*
+ ADDON_ACTION_FORWARD = 16,
+
+ /// @brief <b>`17 `</b>: Can be used to specify specific action in a window, Playback control is handled in ADDON_ACTION_PLAYER_*
+ ADDON_ACTION_REWIND = 17,
+
+ /// @brief <b>`18 `</b>: Toggle between GUI and movie or GUI and visualisation.
+ ADDON_ACTION_SHOW_GUI = 18,
+
+ /// @brief <b>`19 `</b>: Toggle quick-access zoom modes. Can b used in videoFullScreen.zml window id=2005
+ ADDON_ACTION_ASPECT_RATIO = 19,
+
+ /// @brief <b>`20 `</b>: Seek +1% in the movie. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_STEP_FORWARD = 20,
+
+ /// @brief <b>`21 `</b>: Seek -1% in the movie. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_STEP_BACK = 21,
+
+ /// @brief <b>`22 `</b>: Seek +10% in the movie. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_BIG_STEP_FORWARD = 22,
+
+ /// @brief <b>`23 `</b>: Seek -10% in the movie. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_BIG_STEP_BACK = 23,
+
+ /// @brief <b>`24 `</b>: Show/hide OSD. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_SHOW_OSD = 24,
+
+ /// @brief <b>`25 `</b>: Turn subtitles on/off. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_SHOW_SUBTITLES = 25,
+
+ /// @brief <b>`26 `</b>: Switch to next subtitle of movie. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_NEXT_SUBTITLE = 26,
+
+ /// @brief <b>`27 `</b>: Show debug info for VideoPlayer
+ ADDON_ACTION_PLAYER_DEBUG = 27,
+
+ /// @brief <b>`28 `</b>: Show next picture of slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_NEXT_PICTURE = 28,
+
+ /// @brief <b>`29 `</b>: Show previous picture of slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_PREV_PICTURE = 29,
+
+ /// @brief <b>`30 `</b>: Zoom in picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_OUT = 30,
+
+ /// @brief <b>`31 `</b>: Zoom out picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_IN = 31,
+
+ /// @brief <b>`32 `</b>: Used to toggle between source view and destination view. Can be used in myfiles.xml window id=3
+ ADDON_ACTION_TOGGLE_SOURCE_DEST = 32,
+
+ /// @brief <b>`33 `</b>: Used to toggle between current view and playlist view. Can b used in all mymusic xml files
+ ADDON_ACTION_SHOW_PLAYLIST = 33,
+
+ /// @brief <b>`34 `</b>: Used to queue a item to the playlist. Can b used in all mymusic xml files
+ ADDON_ACTION_QUEUE_ITEM = 34,
+
+ /// @brief <b>`35 `</b>: Not used anymore
+ ADDON_ACTION_REMOVE_ITEM = 35,
+
+ /// @brief <b>`36 `</b>: Not used anymore
+ ADDON_ACTION_SHOW_FULLSCREEN = 36,
+
+ /// @brief <b>`37 `</b>: Zoom 1x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_NORMAL = 37,
+
+ /// @brief <b>`38 `</b>: Zoom 2x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_1 = 38,
+
+ /// @brief <b>`39 `</b>: Zoom 3x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_2 = 39,
+
+ /// @brief <b>`40 `</b>: Zoom 4x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_3 = 40,
+
+ /// @brief <b>`41 `</b>: Zoom 5x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_4 = 41,
+
+ /// @brief <b>`42 `</b>: Zoom 6x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_5 = 42,
+
+ /// @brief <b>`43 `</b>: Zoom 7x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_6 = 43,
+
+ /// @brief <b>`44 `</b>: Zoom 8x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_7 = 44,
+
+ /// @brief <b>`45 `</b>: Zoom 9x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_8 = 45,
+
+ /// @brief <b>`46 `</b>: Zoom 10x picture during slideshow. Can b used in slideshow.xml window id=2007
+ ADDON_ACTION_ZOOM_LEVEL_9 = 46,
+
+ /// @brief <b>`47 `</b>: Select next arrow. Can b used in: settingsScreenCalibration.xml windowid=11
+ ADDON_ACTION_CALIBRATE_SWAP_ARROWS = 47,
+
+ /// @brief <b>`48 `</b>: Reset calibration to defaults. Can b used in: `settingsScreenCalibration.xml` windowid=11/settingsUICalibration.xml windowid=10
+ ADDON_ACTION_CALIBRATE_RESET = 48,
+
+ /// @brief <b>`49 `</b>: Analog thumbstick move. Can b used in: `slideshow.xml`
+ /// windowid=2007/settingsScreenCalibration.xml windowid=11/settingsUICalibration.xml
+ /// windowid=10
+ /// @note see also ADDON_ACTION_ANALOG_MOVE_X_LEFT, ADDON_ACTION_ANALOG_MOVE_X_RIGHT,
+ /// ADDON_ACTION_ANALOG_MOVE_Y_UP, ADDON_ACTION_ANALOG_MOVE_Y_DOWN
+ ADDON_ACTION_ANALOG_MOVE = 49,
+
+ /// @brief <b>`50 `</b>: Rotate current picture clockwise during slideshow. Can be used in slideshow.xml window id=2007
+ ADDON_ACTION_ROTATE_PICTURE_CW = 50,
+
+ /// @brief <b>`51 `</b>: Rotate current picture counterclockwise during slideshow. Can be used in slideshow.xml window id=2007
+ ADDON_ACTION_ROTATE_PICTURE_CCW = 51,
+
+ /// @brief <b>`52 `</b>: Decrease subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_SUBTITLE_DELAY_MIN = 52,
+
+ /// @brief <b>`53 `</b>: Increase subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_SUBTITLE_DELAY_PLUS = 53,
+
+ /// @brief <b>`54 `</b>: Increase avsync delay. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_AUDIO_DELAY_MIN = 54,
+
+ /// @brief <b>`55 `</b>: Decrease avsync delay. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_AUDIO_DELAY_PLUS = 55,
+
+ /// @brief <b>`56 `</b>: Select next language in movie. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_AUDIO_NEXT_LANGUAGE = 56,
+
+ /// @brief <b>`57 `</b>: Switch 2 next resolution. Can b used during screen calibration settingsScreenCalibration.xml windowid=11
+ ADDON_ACTION_CHANGE_RESOLUTION = 57,
+
+ /// @brief <b>`58 `</b>: remote keys 0-9. are used by multiple windows
+ /// for example in videoFullScreen.xml window id=2005 you can
+ /// enter time (mmss) to jump to particular point in the movie
+ /// with spincontrols you can enter 3digit number to quickly set
+ /// spincontrol to desired value
+ ///
+ /// Remote key 0
+ ADDON_ACTION_REMOTE_0 = 58,
+
+ /// @brief <b>`59 `</b>: Remote key 1
+ ADDON_ACTION_REMOTE_1 = 59,
+
+ /// @brief <b>`60 `</b>: Remote key 2
+ ADDON_ACTION_REMOTE_2 = 60,
+
+ /// @brief <b>`61 `</b>: Remote key 3
+ ADDON_ACTION_REMOTE_3 = 61,
+
+ /// @brief <b>`62 `</b>: Remote key 4
+ ADDON_ACTION_REMOTE_4 = 62,
+
+ /// @brief <b>`63 `</b>: Remote key 5
+ ADDON_ACTION_REMOTE_5 = 63,
+
+ /// @brief <b>`64 `</b>: Remote key 6
+ ADDON_ACTION_REMOTE_6 = 64,
+
+ /// @brief <b>`65 `</b>: Remote key 7
+ ADDON_ACTION_REMOTE_7 = 65,
+
+ /// @brief <b>`66 `</b>: Remote key 8
+ ADDON_ACTION_REMOTE_8 = 66,
+
+ /// @brief <b>`67 `</b>: Remote key 9
+ ADDON_ACTION_REMOTE_9 = 67,
+
+ /// @brief <b>`69 `</b>: Show player process info (video decoder, pixel format, pvr signal strength and the like
+ ADDON_ACTION_PLAYER_PROCESS_INFO = 69,
+
+ /// @brief <b>`70 `</b>: Program select.
+ ADDON_ACTION_PLAYER_PROGRAM_SELECT = 70,
+
+ /// @brief <b>`71 `</b>: Resolution select.
+ ADDON_ACTION_PLAYER_RESOLUTION_SELECT = 71,
+
+ /// @brief <b>`76 `</b>: Jumps a few seconds back during playback of movie. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_SMALL_STEP_BACK = 76,
+
+ /// @brief <b>`77 `</b>: FF in current file played. global action, can be used anywhere
+ ADDON_ACTION_PLAYER_FORWARD = 77,
+
+ /// @brief <b>`78 `</b>: RW in current file played. global action, can be used anywhere
+ ADDON_ACTION_PLAYER_REWIND = 78,
+
+ /// @brief <b>`79 `</b>: Play current song. Unpauses song and sets playspeed to 1x. global action, can be used anywhere
+ ADDON_ACTION_PLAYER_PLAY = 79,
+
+ /// @brief <b>`80 `</b>: Delete current selected item. Can be used in myfiles.xml window id=3 and in myvideoTitle.xml window id=25
+ ADDON_ACTION_DELETE_ITEM = 80,
+
+ /// @brief <b>`81 `</b>: Copy current selected item. Can be used in myfiles.xml window id=3
+ ADDON_ACTION_COPY_ITEM = 81,
+
+ /// @brief <b>`82 `</b>: move current selected item. Can be used in myfiles.xml window id=3
+ ADDON_ACTION_MOVE_ITEM = 82,
+
+ /// @brief <b>`85 `</b>: Take a screenshot.
+ ADDON_ACTION_TAKE_SCREENSHOT = 85,
+
+ /// @brief <b>`87 `</b>: Rename item.
+ ADDON_ACTION_RENAME_ITEM = 87,
+
+ /// @brief <b>`87 `</b>: Volume up.
+ ADDON_ACTION_VOLUME_UP = 88,
+
+ /// @brief <b>`87 `</b>: Volume down.
+ ADDON_ACTION_VOLUME_DOWN = 89,
+
+ /// @brief <b>`90 `</b>: Volume amplication.
+ ADDON_ACTION_VOLAMP = 90,
+
+ /// @brief <b>`90 `</b>: Mute.
+ ADDON_ACTION_MUTE = 91,
+
+ /// @brief <b>`90 `</b>: Nav back.
+ ADDON_ACTION_NAV_BACK = 92,
+
+ /// @brief <b>`90 `</b>: Volume amp up,
+ ADDON_ACTION_VOLAMP_UP = 93,
+
+ /// @brief <b>`94 `</b>: Volume amp down.
+ ADDON_ACTION_VOLAMP_DOWN = 94,
+
+ /// @brief <b>`95 `</b>: Creates an episode bookmark on the currently playing video file containing more than one
+ /// episode
+ ADDON_ACTION_CREATE_EPISODE_BOOKMARK = 95,
+
+ /// @brief <b>`96 `</b>: Creates a bookmark of the currently playing video file
+ ADDON_ACTION_CREATE_BOOKMARK = 96,
+
+ /// @brief <b>`97 `</b>: Goto the next chapter, if not available perform a big step forward
+ ADDON_ACTION_CHAPTER_OR_BIG_STEP_FORWARD = 97,
+
+ /// @brief <b>`98 `</b>: Goto the previous chapter, if not available perform a big step back
+ ADDON_ACTION_CHAPTER_OR_BIG_STEP_BACK = 98,
+
+ /// @brief <b>`99 `</b>: Switch to next subtitle of movie, but will not enable/disable the subtitles. Can be used
+ /// in videoFullScreen.xml window id=2005
+ ADDON_ACTION_CYCLE_SUBTITLE = 99,
+
+ /// @brief <b>`100`</b>: Mouse action values start.
+ ///
+ /// Ends with @ref ADDON_ACTION_MOUSE_END.
+ ADDON_ACTION_MOUSE_START = 100,
+
+ /// @brief <b>`100`</b>: Mouse left click.
+ ADDON_ACTION_MOUSE_LEFT_CLICK = 100,
+
+ /// @brief <b>`101`</b>: Mouse right click.
+ ADDON_ACTION_MOUSE_RIGHT_CLICK = 101,
+
+ /// @brief <b>`102`</b>: Mouse middle click.
+ ADDON_ACTION_MOUSE_MIDDLE_CLICK = 102,
+
+ /// @brief <b>`103`</b>: Mouse double click.
+ ADDON_ACTION_MOUSE_DOUBLE_CLICK = 103,
+
+ /// @brief <b>`104`</b>: Mouse wheel up.
+ ADDON_ACTION_MOUSE_WHEEL_UP = 104,
+
+ /// @brief <b>`105`</b>: Mouse wheel down.
+ ADDON_ACTION_MOUSE_WHEEL_DOWN = 105,
+
+ /// @brief <b>`106`</b>: Mouse drag.
+ ADDON_ACTION_MOUSE_DRAG = 106,
+
+ /// @brief <b>`107`</b>: Mouse move.
+ ADDON_ACTION_MOUSE_MOVE = 107,
+
+ /// @brief <b>`108`</b>: Mouse long click.
+ ADDON_ACTION_MOUSE_LONG_CLICK = 108,
+
+ /// @brief <b>`109`</b>: Mouse drag end.
+ ADDON_ACTION_MOUSE_DRAG_END = 109,
+
+ /// @brief <b>`109`</b>: Mouse action values end.
+ ///
+ /// Starts with @ref ADDON_ACTION_MOUSE_START.
+ ADDON_ACTION_MOUSE_END = 109,
+
+ /// @brief <b>`110`</b>: Backspace.
+ ADDON_ACTION_BACKSPACE = 110,
+
+ /// @brief <b>`111`</b>: Scroll up.
+ ADDON_ACTION_SCROLL_UP = 111,
+
+ /// @brief <b>`112`</b>: Scroll down.
+ ADDON_ACTION_SCROLL_DOWN = 112,
+
+ /// @brief <b>`113`</b>: Analog forward.
+ ADDON_ACTION_ANALOG_FORWARD = 113,
+
+ /// @brief <b>`114`</b>: Analog rewind.
+ ADDON_ACTION_ANALOG_REWIND = 114,
+
+ /// @brief <b>`115`</b>: move item up in playlist
+ ADDON_ACTION_MOVE_ITEM_UP = 115,
+
+ /// @brief <b>`116`</b>: move item down in playlist
+ ADDON_ACTION_MOVE_ITEM_DOWN = 116,
+
+ /// @brief <b>`117`</b>: pops up the context menu
+ ADDON_ACTION_CONTEXT_MENU = 117,
+
+ /// @brief <b>`118`</b>: stuff for virtual keyboard shortcuts
+ ADDON_ACTION_SHIFT = 118,
+
+ /// @brief <b>`119`</b>: stuff for virtual keyboard shortcuts
+ ADDON_ACTION_SYMBOLS = 119,
+
+ /// @brief <b>`120`</b>: stuff for virtual keyboard shortcuts
+ ADDON_ACTION_CURSOR_LEFT = 120,
+
+ /// @brief <b>`121`</b>: stuff for virtual keyboard shortcuts
+ ADDON_ACTION_CURSOR_RIGHT = 121,
+
+ /// @brief <b>`122`</b>: Build in function
+ ADDON_ACTION_BUILT_IN_FUNCTION = 122,
+
+ /// @brief <b>`114`</b>: Displays current time, can be used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_SHOW_OSD_TIME = 123,
+
+ /// @brief <b>`124`</b>: Seeks forward, and displays the seek bar.
+ ADDON_ACTION_ANALOG_SEEK_FORWARD = 124,
+
+ /// @brief <b>`125`</b>: Seeks backward, and displays the seek bar.
+ ADDON_ACTION_ANALOG_SEEK_BACK = 125,
+
+ /// @brief <b>`126`</b>: Visualization preset show.
+ ADDON_ACTION_VIS_PRESET_SHOW = 126,
+
+ /// @brief <b>`128`</b>: Visualization preset next.
+ ADDON_ACTION_VIS_PRESET_NEXT = 128,
+
+ /// @brief <b>`129`</b>: Visualization preset previous.
+ ADDON_ACTION_VIS_PRESET_PREV = 129,
+
+ /// @brief <b>`130`</b>: Visualization preset lock.
+ ADDON_ACTION_VIS_PRESET_LOCK = 130,
+
+ /// @brief <b>`131`</b>: Visualization preset random.
+ ADDON_ACTION_VIS_PRESET_RANDOM = 131,
+
+ /// @brief <b>`132`</b>: Visualization preset plus.
+ ADDON_ACTION_VIS_RATE_PRESET_PLUS = 132,
+
+ /// @brief <b>`133`</b>: Visualization preset minus.
+ ADDON_ACTION_VIS_RATE_PRESET_MINUS = 133,
+
+ /// @brief <b>`134`</b>: Show Videomenu
+ ADDON_ACTION_SHOW_VIDEOMENU = 134,
+
+ /// @brief <b>`135`</b>: Enter.
+ ADDON_ACTION_ENTER = 135,
+
+ /// @brief <b>`136`</b>: Increase rating.
+ ADDON_ACTION_INCREASE_RATING = 136,
+
+ /// @brief <b>`137`</b>: Decrease rating.
+ ADDON_ACTION_DECREASE_RATING = 137,
+
+ /// @brief <b>`138`</b>: Switch to next scene/cutpoint in movie.
+ ADDON_ACTION_NEXT_SCENE = 138,
+
+ /// @brief <b>`139`</b>: Switch to previous scene/cutpoint in movie.
+ ADDON_ACTION_PREV_SCENE = 139,
+
+ /// @brief <b>`140`</b>: Jump through a list or container to next letter.
+ ADDON_ACTION_NEXT_LETTER = 140,
+
+ /// @brief <b>`141`</b>: Jump through a list or container to previous letter.
+ ADDON_ACTION_PREV_LETTER = 141,
+
+ /// @brief <b>`142`</b>: Jump direct to a particular letter using SMS-style input
+ ///
+ /// Jump to SMS2.
+ ADDON_ACTION_JUMP_SMS2 = 142,
+
+ /// @brief <b>`143`</b>: Jump to SMS3.
+ ADDON_ACTION_JUMP_SMS3 = 143,
+
+ /// @brief <b>`144`</b>: Jump to SMS4.
+ ADDON_ACTION_JUMP_SMS4 = 144,
+
+ /// @brief <b>`145`</b>: Jump to SMS5.
+ ADDON_ACTION_JUMP_SMS5 = 145,
+
+ /// @brief <b>`146`</b>: Jump to SMS6.
+ ADDON_ACTION_JUMP_SMS6 = 146,
+
+ /// @brief <b>`147`</b>: Jump to SMS7.
+ ADDON_ACTION_JUMP_SMS7 = 147,
+
+ /// @brief <b>`148`</b>: Jump to SMS8.
+ ADDON_ACTION_JUMP_SMS8 = 148,
+
+ /// @brief <b>`149`</b>: Jump to SMS9.
+ ADDON_ACTION_JUMP_SMS9 = 149,
+
+ /// @brief <b>`150`</b>: Filter clear.
+ ADDON_ACTION_FILTER_CLEAR = 150,
+
+ /// @brief <b>`151`</b>: Filter SMS2.
+ ADDON_ACTION_FILTER_SMS2 = 151,
+
+ /// @brief <b>`152`</b>: Filter SMS3.
+ ADDON_ACTION_FILTER_SMS3 = 152,
+
+ /// @brief <b>`153`</b>: Filter SMS4.
+ ADDON_ACTION_FILTER_SMS4 = 153,
+
+ /// @brief <b>`154`</b>: Filter SMS5.
+ ADDON_ACTION_FILTER_SMS5 = 154,
+
+ /// @brief <b>`155`</b>: Filter SMS6.
+ ADDON_ACTION_FILTER_SMS6 = 155,
+
+ /// @brief <b>`156`</b>: Filter SMS7.
+ ADDON_ACTION_FILTER_SMS7 = 156,
+
+ /// @brief <b>`157`</b>: Filter SMS8.
+ ADDON_ACTION_FILTER_SMS8 = 157,
+
+ /// @brief <b>`158`</b>: Filter SMS9.
+ ADDON_ACTION_FILTER_SMS9 = 158,
+
+ /// @brief <b>`159`</b>: First page.
+ ADDON_ACTION_FIRST_PAGE = 159,
+
+ /// @brief <b>`160`</b>: Last page.
+ ADDON_ACTION_LAST_PAGE = 160,
+
+ /// @brief <b>`161`</b>: Audio delay.
+ ADDON_ACTION_AUDIO_DELAY = 161,
+
+ /// @brief <b>`162`</b>: Subtitle delay.
+ ADDON_ACTION_SUBTITLE_DELAY = 162,
+
+ /// @brief <b>`163`</b>: Menu.
+ ADDON_ACTION_MENU = 163,
+
+ /// @brief <b>`164`</b>: Set rating.
+ ADDON_ACTION_SET_RATING = 164,
+
+ /// @brief <b>`170`</b>: Record.
+ ADDON_ACTION_RECORD = 170,
+
+ /// @brief <b>`180`</b>: Paste.
+ ADDON_ACTION_PASTE = 180,
+
+ /// @brief <b>`181`</b>: Next control.
+ ADDON_ACTION_NEXT_CONTROL = 181,
+
+ /// @brief <b>`182`</b>: Previous control.
+ ADDON_ACTION_PREV_CONTROL = 182,
+
+ /// @brief <b>`183`</b>: Channel switch.
+ ADDON_ACTION_CHANNEL_SWITCH = 183,
+
+ /// @brief <b>`184`</b>: Channel up.
+ ADDON_ACTION_CHANNEL_UP = 184,
+
+ /// @brief <b>`185`</b>: Channel down.
+ ADDON_ACTION_CHANNEL_DOWN = 185,
+
+ /// @brief <b>`186`</b>: Next channel group.
+ ADDON_ACTION_NEXT_CHANNELGROUP = 186,
+
+ /// @brief <b>`187`</b>: Previous channel group.
+ ADDON_ACTION_PREVIOUS_CHANNELGROUP = 187,
+
+ /// @brief <b>`188`</b>: PVR play.
+ ADDON_ACTION_PVR_PLAY = 188,
+
+ /// @brief <b>`189`</b>: PVR play TV.
+ ADDON_ACTION_PVR_PLAY_TV = 189,
+
+ /// @brief <b>`190`</b>: PVR play radio.
+ ADDON_ACTION_PVR_PLAY_RADIO = 190,
+
+ /// @brief <b>`191`</b>: PVR show timer rule.
+ ADDON_ACTION_PVR_SHOW_TIMER_RULE = 191,
+
+ /// @brief <b>`192`</b>: Channel number sep
+ ADDON_ACTION_CHANNEL_NUMBER_SEP = 192,
+
+ /// @brief <b>`193`</b>: PVR announce reminders
+ ADDON_ACTION_PVR_ANNOUNCE_REMINDERS = 193,
+
+ /// @brief <b>`199`</b>: Switch 2 desktop resolution
+ ADDON_ACTION_TOGGLE_FULLSCREEN = 199,
+
+ /// @brief <b>`200`</b>: Toggle watched status (videos)
+ ADDON_ACTION_TOGGLE_WATCHED = 200,
+
+ /// @brief <b>`201`</b>: Scan item
+ ADDON_ACTION_SCAN_ITEM = 201,
+
+ /// @brief <b>`202`</b>: Switch digital <-> analog
+ ADDON_ACTION_TOGGLE_DIGITAL_ANALOG = 202,
+
+ /// @brief <b>`203`</b>: Reloads CButtonTranslator's keymaps
+ ADDON_ACTION_RELOAD_KEYMAPS = 203,
+
+ /// @brief <b>`204`</b>: Start the GUIControlProfiler running
+ ADDON_ACTION_GUIPROFILE_BEGIN = 204,
+
+ /// @brief <b>`215`</b>: Teletext Color button <b>Red</b> to control TopText
+ ADDON_ACTION_TELETEXT_RED = 215,
+
+ /// @brief <b>`216`</b>: Teletext Color button <b>Green</b> to control TopText
+ ADDON_ACTION_TELETEXT_GREEN = 216,
+
+ /// @brief <b>`217`</b>: Teletext Color button <b>Yellow</b> to control TopText
+ ADDON_ACTION_TELETEXT_YELLOW = 217,
+
+ /// @brief <b>`218`</b>: Teletext Color button <b>Blue</b> to control TopText
+ ADDON_ACTION_TELETEXT_BLUE = 218,
+
+ /// @brief <b>`219`</b>: Increase par.
+ ADDON_ACTION_INCREASE_PAR = 219,
+
+ /// @brief <b>`220`</b>: Decrease par.
+ ADDON_ACTION_DECREASE_PAR = 220,
+
+ /// @brief <b>`227`</b>: Shift up video image in VideoPlayer
+ ADDON_ACTION_VSHIFT_UP = 227,
+
+ /// @brief <b>`228`</b>: Shift down video image in VideoPlayer
+ ADDON_ACTION_VSHIFT_DOWN = 228,
+
+ /// @brief <b>`229`</b>: Play/pause. If playing it pauses, if paused it plays.
+ ADDON_ACTION_PLAYER_PLAYPAUSE = 229,
+
+ /// @brief <b>`230`</b>: Shift up subtitles in VideoPlayer
+ ADDON_ACTION_SUBTITLE_VSHIFT_UP = 230,
+
+ /// @brief <b>`231`</b>: Shift down subtitles in VideoPlayer
+ ADDON_ACTION_SUBTITLE_VSHIFT_DOWN = 231,
+
+ /// @brief <b>`232`</b>: Toggle vertical alignment of subtitles
+ ADDON_ACTION_SUBTITLE_ALIGN = 232,
+
+ /// @brief <b>`233`</b>: Filter.
+ ADDON_ACTION_FILTER = 233,
+
+ /// @brief <b>`234`</b>: Switch player.
+ ADDON_ACTION_SWITCH_PLAYER = 234,
+
+ /// @brief <b>`235`</b>: Stereo mode next.
+ ADDON_ACTION_STEREOMODE_NEXT = 235,
+
+ /// @brief <b>`236`</b>: Stereo mode previous.
+ ADDON_ACTION_STEREOMODE_PREVIOUS = 236,
+
+ /// @brief <b>`237`</b>: Turns 3d mode on/off.
+ ADDON_ACTION_STEREOMODE_TOGGLE = 237,
+
+ /// @brief <b>`238`</b>: Stereo mode select.
+ ADDON_ACTION_STEREOMODE_SELECT = 238,
+
+ /// @brief <b>`239`</b>: Stereo mode to mono.
+ ADDON_ACTION_STEREOMODE_TOMONO = 239,
+
+ /// @brief <b>`240`</b>: Stereo mode set.
+ ADDON_ACTION_STEREOMODE_SET = 240,
+
+ /// @brief <b>`241`</b>: Settings reset.
+ ADDON_ACTION_SETTINGS_RESET = 241,
+
+ /// @brief <b>`242`</b>: Settings level change.
+ ADDON_ACTION_SETTINGS_LEVEL_CHANGE = 242,
+
+ /// @brief <b>`243`</b>: Show autoclosing OSD. Can b used in videoFullScreen.xml window id=2005
+ ADDON_ACTION_TRIGGER_OSD = 243,
+
+ /// @brief <b>`244`</b>: Input text.
+ ADDON_ACTION_INPUT_TEXT = 244,
+
+ /// @brief <b>`245`</b>: Volume set.
+ ADDON_ACTION_VOLUME_SET = 245,
+
+ /// @brief <b>`246`</b>: Toggle commercial skip.
+ ADDON_ACTION_TOGGLE_COMMSKIP = 246,
+
+ /// @brief <b>`247`</b>: Browse for subtitle. Can be used in videofullscreen
+ ADDON_ACTION_BROWSE_SUBTITLE = 247,
+
+ /// @brief <b>`248`</b>: Send a reset command to the active game
+ ADDON_ACTION_PLAYER_RESET = 248,
+
+ /// @brief <b>`249`</b>: Toggle font. Used in TextViewer dialog
+ ADDON_ACTION_TOGGLE_FONT = 249,
+
+ /// @brief <b>`250`</b>: Cycle video streams. Used in videofullscreen.
+ ADDON_ACTION_VIDEO_NEXT_STREAM = 250,
+
+ /// @brief <b>`251`</b>: Used to queue an item to the next position in the playlist
+ ADDON_ACTION_QUEUE_ITEM_NEXT = 251,
+
+ /// @brief <b>`247`</b>: Toggle display HDR on/off
+ ADDON_ACTION_HDR_TOGGLE = 260,
+
+ /// @brief <b>`300`</b>: Voice actions
+ ADDON_ACTION_VOICE_RECOGNIZE = 300,
+
+ // Number 347 used om front by ADDON_ACTION_BROWSE_SUBTITLE
+
+ /// @brief <b>`401`</b>: Touch actions
+ ADDON_ACTION_TOUCH_TAP = 401,
+
+ /// @brief <b>`410`</b>: Touch actions
+ ADDON_ACTION_TOUCH_TAP_TEN = 410,
+
+ /// @brief <b>`411`</b>: Touch actions
+ ADDON_ACTION_TOUCH_LONGPRESS = 411,
+
+ /// @brief <b>`412`</b>: Touch actions
+ ADDON_ACTION_TOUCH_LONGPRESS_TEN = 420,
+
+ /// @brief <b>`500`</b>: Gesture notify.
+ ADDON_ACTION_GESTURE_NOTIFY = 500,
+
+ /// @brief <b>`501`</b>: Gesture begin.
+ ADDON_ACTION_GESTURE_BEGIN = 501,
+
+ /// @brief <b>`502`</b>: Send action with point and currentPinchScale (fingers together < 1.0 -> fingers apart > 1.0)
+ ADDON_ACTION_GESTURE_ZOOM = 502,
+
+ /// @brief <b>`503`</b>: Gesture rotate.
+ ADDON_ACTION_GESTURE_ROTATE = 503,
+
+ /// @brief <b>`504`</b>: Gesture pan.
+ ADDON_ACTION_GESTURE_PAN = 504,
+
+ /// @brief <b>`505`</b>: Gesture was interrupted in unspecified state
+ ADDON_ACTION_GESTURE_ABORT = 505,
+
+ /// @brief <b>`511`</b>: Gesture swipe left.
+ ADDON_ACTION_GESTURE_SWIPE_LEFT = 511,
+
+ /// @brief <b>`520`</b>: Gesture swipe left ten
+ ADDON_ACTION_GESTURE_SWIPE_LEFT_TEN = 520,
+
+ /// @brief <b>`521`</b>: Gesture swipe right
+ ADDON_ACTION_GESTURE_SWIPE_RIGHT = 521,
+
+ /// @brief <b>`530`</b>: Gesture swipe right ten
+ ADDON_ACTION_GESTURE_SWIPE_RIGHT_TEN = 530,
+
+ /// @brief <b>`531`</b>: Gesture swipe up
+ ADDON_ACTION_GESTURE_SWIPE_UP = 531,
+
+ /// @brief <b>`540`</b>: Gesture swipe up ten
+ ADDON_ACTION_GESTURE_SWIPE_UP_TEN = 540,
+
+ /// @brief <b>`541`</b>: Gesture swipe down.
+ ADDON_ACTION_GESTURE_SWIPE_DOWN = 541,
+
+ /// @brief <b>`550`</b>: Gesture swipe down ten.
+ ADDON_ACTION_GESTURE_SWIPE_DOWN_TEN = 550,
+
+ /// @brief <b>`599`</b>: 5xx is reserved for additional gesture actions
+ ADDON_ACTION_GESTURE_END = 599,
+
+ // other, non-gesture actions
+
+ /// @brief <b>`601`</b>: Analog thumbstick move, horizontal axis, left; see ADDON_ACTION_ANALOG_MOVE
+ ADDON_ACTION_ANALOG_MOVE_X_LEFT = 601,
+
+ /// @brief <b>`602`</b>: Analog thumbstick move, horizontal axis, right; see ADDON_ACTION_ANALOG_MOVE
+ ADDON_ACTION_ANALOG_MOVE_X_RIGHT = 602,
+
+ /// @brief <b>`603`</b>: Analog thumbstick move, vertical axis, up; see ADDON_ACTION_ANALOG_MOVE
+ ADDON_ACTION_ANALOG_MOVE_Y_UP = 603,
+
+ /// @brief <b>`604`</b>: Analog thumbstick move, vertical axis, down; see ADDON_ACTION_ANALOG_MOVE
+ ADDON_ACTION_ANALOG_MOVE_Y_DOWN = 604,
+
+ /// @brief <b>`998`</b>: ERROR action is used to play an error sound.
+ ADDON_ACTION_ERROR = 998,
+
+ /// @brief <b>`999`</b>: The NOOP action can be specified to disable an input event. This is
+ /// useful in user keyboard.xml etc to disable actions specified in the
+ /// system mappings.
+ ADDON_ACTION_NOOP = 999
+ ///@}
+};
+///@}
+
+#endif /* !C_API_GUI_ACTION_IDS_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/list_item.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/list_item.h
new file mode 100644
index 0000000..d2120ac
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/list_item.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_LIST_ITEM_H
+#define C_API_GUI_LIST_ITEM_H
+
+#include "definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_listItem
+ {
+ KODI_GUI_LISTITEM_HANDLE(*create)
+ (KODI_HANDLE kodiBase,
+ const char* label,
+ const char* label2,
+ const char* path);
+ void (*destroy)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+
+ char* (*get_label)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ void (*set_label)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* label);
+ char* (*get_label2)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ void (*set_label2)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* label);
+ char* (*get_art)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* type);
+ void (*set_art)(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* type,
+ const char* image);
+ char* (*get_path)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ void (*set_path)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* path);
+ char* (*get_property)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* key);
+ void (*set_property)(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* key,
+ const char* value);
+ void (*select)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, bool select);
+ bool (*is_selected)(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ } AddonToKodiFuncTable_kodi_gui_listItem;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_LIST_ITEM_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/window.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/window.h
new file mode 100644
index 0000000..d7181c0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/window.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#ifndef C_API_GUI_WINDOW_H
+#define C_API_GUI_WINDOW_H
+
+#include "definitions.h"
+#include "input/action_ids.h"
+
+#include <stddef.h>
+
+#define ADDON_MAX_CONTEXT_ENTRIES 20
+#define ADDON_MAX_CONTEXT_ENTRY_NAME_LENGTH 80
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ typedef struct gui_context_menu_pair
+ {
+ unsigned int id;
+ char name[ADDON_MAX_CONTEXT_ENTRY_NAME_LENGTH];
+ } gui_context_menu_pair;
+
+ typedef struct AddonToKodiFuncTable_kodi_gui_window
+ {
+ /* Window creation functions */
+ KODI_GUI_WINDOW_HANDLE(*create)
+ (KODI_HANDLE kodiBase,
+ const char* xml_filename,
+ const char* default_skin,
+ bool as_dialog,
+ bool is_media);
+ void (*destroy)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+
+ void (*set_callbacks)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_CLIENT_HANDLE clienthandle,
+ bool (*CBInit)(KODI_GUI_CLIENT_HANDLE),
+ bool (*CBFocus)(KODI_GUI_CLIENT_HANDLE, int),
+ bool (*CBClick)(KODI_GUI_CLIENT_HANDLE, int),
+ bool (*CBOnAction)(KODI_GUI_CLIENT_HANDLE, enum ADDON_ACTION),
+ void (*CBGetContextButtons)(
+ KODI_GUI_CLIENT_HANDLE, int, gui_context_menu_pair*, unsigned int*),
+ bool (*CBOnContextButton)(KODI_GUI_CLIENT_HANDLE, int, unsigned int));
+ bool (*show)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ bool (*close)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ bool (*do_modal)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+
+ /* Window control functions */
+ bool (*set_focus_id)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ int (*get_focus_id)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ void (*set_control_label)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ const char* label);
+ void (*set_control_visible)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ bool visible);
+ void (*set_control_selected)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ bool selected);
+
+ /* Window property functions */
+ void (*set_property)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ const char* value);
+ void (*set_property_int)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ int value);
+ void (*set_property_bool)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ bool value);
+ void (*set_property_double)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ double value);
+ char* (*get_property)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, const char* key);
+ int (*get_property_int)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, const char* key);
+ bool (*get_property_bool)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, const char* key);
+ double (*get_property_double)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key);
+ void (*clear_properties)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ void (*clear_property)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, const char* key);
+
+ /* List item functions */
+ void (*clear_item_list)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ void (*add_list_item)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_LISTITEM_HANDLE item,
+ int list_position);
+ void (*remove_list_item_from_position)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position);
+ void (*remove_list_item)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_LISTITEM_HANDLE item);
+ KODI_GUI_LISTITEM_HANDLE(*get_list_item)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int list_position);
+ void (*set_current_list_position)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position);
+ int (*get_current_list_position)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ int (*get_list_size)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ void (*set_container_property)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ const char* value);
+ void (*set_container_content)(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* value);
+ int (*get_current_container_id)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+
+ /* Various functions */
+ void (*mark_dirty_region)(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+
+ /* GUI control access functions */
+ KODI_GUI_CONTROL_HANDLE(*get_control_button)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_edit)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_fade_label)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_image)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_label)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_progress)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_radio_button)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_render_addon)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_settings_slider)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_slider)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_spin)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_text_box)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy1)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy2)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy3)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy4)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy5)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy6)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy7)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy8)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy9)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ KODI_GUI_CONTROL_HANDLE(*get_control_dummy10)
+ (KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ /* This above used to add new get_control_* functions */
+ } AddonToKodiFuncTable_kodi_gui_window;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !C_API_GUI_WINDOW_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/network.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/network.h
new file mode 100644
index 0000000..8bd987b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/network.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef C_API_NETWORK_H
+#define C_API_NETWORK_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ /*
+ * For interface between add-on and kodi.
+ *
+ * This structure defines the addresses of functions stored inside Kodi which
+ * are then available for the add-on to call
+ *
+ * All function pointers there are used by the C++ interface functions below.
+ * You find the set of them on xbmc/addons/interfaces/General.cpp
+ *
+ * Note: For add-on development itself this is not needed
+ */
+ typedef struct AddonToKodiFuncTable_kodi_network
+ {
+ bool (*wake_on_lan)(void* kodiBase, const char* mac);
+ char* (*get_ip_address)(void* kodiBase);
+ char* (*dns_lookup)(void* kodiBase, const char* url, bool* ret);
+ char* (*url_encode)(void* kodiBase, const char* url);
+ char* (*get_hostname)(void* kodiBase);
+ bool (*is_local_host)(void* kodiBase, const char* hostname);
+ bool (*is_host_on_lan)(void* kodiBase, const char* hostname, bool offLineCheck);
+ char* (*get_user_agent)(void* kodiBase);
+ } AddonToKodiFuncTable_kodi_network;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* C_API_NETWORK_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/CMakeLists.txt
new file mode 100644
index 0000000..0015a90
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_platform)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/CMakeLists.txt
new file mode 100644
index 0000000..3704ed6
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ $<$<STREQUAL:${CORE_SYSTEM_NAME},android>:system.h>
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_c-api_platform_android)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/system.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/system.h
new file mode 100644
index 0000000..c2174d0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/system.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+/*---AUTO_GEN_PARSE<$$CORE_SYSTEM_NAME:android>---*/
+
+#ifndef C_API_PLATFORM_ANDROID_H
+#define C_API_PLATFORM_ANDROID_H
+
+#define INTERFACE_ANDROID_SYSTEM_NAME "ANDROID_SYSTEM"
+#define INTERFACE_ANDROID_SYSTEM_VERSION "1.0.2"
+#define INTERFACE_ANDROID_SYSTEM_VERSION_MIN "1.0.1"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ struct AddonToKodiFuncTable_android_system
+ {
+ void* (*get_jni_env)();
+ int (*get_sdk_version)();
+ const char *(*get_class_name)();
+ };
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !C_API_PLATFORM_ANDROID_H */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/gui/CMakeLists.txt
new file mode 100644
index 0000000..e94f764
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ General.h
+ ListItem.h
+ Window.h
+ renderHelper.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_gui)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h
new file mode 100644
index 0000000..0c639ef
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/gui/general.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+
+//==============================================================================
+/// @addtogroup cpp_kodi_gui_general
+/// Permits the use of the required functions of the add-on to Kodi.
+///
+/// These are pure functions them no other initialization need.
+///
+/// It has the header @ref kodi/gui/General.h "#include <kodi/gui/General.h>" be included
+/// to enjoy it.
+///
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Performs a graphical lock of rendering engine.
+///
+inline void ATTR_DLL_LOCAL Lock()
+{
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->general->lock();
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Performs a graphical unlock of previous locked rendering engine.
+///
+inline void ATTR_DLL_LOCAL Unlock()
+{
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->general->unlock();
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Return the the current screen height with pixel.
+///
+/// @return Screen height with pixel
+///
+inline int ATTR_DLL_LOCAL GetScreenHeight()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->general->get_screen_height(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Return the the current screen width with pixel.
+///
+/// @return Screen width with pixel
+///
+inline int ATTR_DLL_LOCAL GetScreenWidth()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->general->get_screen_width(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Return the the current screen rendering resolution.
+///
+/// @return Current screen rendering resolution
+///
+inline int ATTR_DLL_LOCAL GetVideoResolution()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->general->get_video_resolution(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Returns the id for the current 'active' dialog as an integer.
+///
+/// @return The currently active dialog Id
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// ..
+/// int wid = kodi::gui::GetCurrentWindowDialogId();
+/// ..
+/// ~~~~~~~~~~~~~
+///
+inline int ATTR_DLL_LOCAL GetCurrentWindowDialogId()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->general->get_current_window_dialog_id(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Returns the id for the current 'active' window as an integer.
+///
+/// @return The currently active window Id
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// ..
+/// int wid = kodi::gui::GetCurrentWindowId();
+/// ..
+/// ~~~~~~~~~~~~~
+///
+inline int ATTR_DLL_LOCAL GetCurrentWindowId()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->general->get_current_window_id(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief To get hardware specific device context interface.
+///
+/// @return A pointer to the used device with @ref cpp_kodi_Defs_HardwareContext "kodi::HardwareContext"
+///
+/// @warning This function is only be supported under Windows, on all other
+/// OS it return `nullptr`!
+///
+/// @note Returned Windows class pointer is `ID3D11DeviceContext1`.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <d3d11_1.h>
+/// ..
+/// ID3D11DeviceContext1* context = static_cast<ID3D11DeviceContext1*>(kodi::gui::GetHWContext());
+/// ..
+/// ~~~~~~~~~~~~~
+///
+inline kodi::HardwareContext GetHWContext()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->general->get_hw_context(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Get Adjust refresh rate setting status.
+///
+/// @return The Adjust refresh rate setting status
+///
+inline AdjustRefreshRateStatus ATTR_DLL_LOCAL GetAdjustRefreshRateStatus()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->general->get_adjust_refresh_rate_status(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/ListItem.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/ListItem.h
new file mode 100644
index 0000000..0d3e057
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/ListItem.h
@@ -0,0 +1,345 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/gui/list_item.h"
+
+#ifdef __cplusplus
+
+#include <memory>
+
+namespace kodi
+{
+namespace gui
+{
+
+class CWindow;
+
+class ATTR_DLL_LOCAL CAddonGUIControlBase
+{
+public:
+ KODI_GUI_LISTITEM_HANDLE GetControlHandle() const { return m_controlHandle; }
+
+protected:
+ explicit CAddonGUIControlBase(CAddonGUIControlBase* window)
+ : m_controlHandle(nullptr),
+ m_interface(::kodi::addon::CPrivateBase::m_interface->toKodi),
+ m_Window(window)
+ {
+ }
+
+ virtual ~CAddonGUIControlBase() = default;
+
+ friend class CWindow;
+
+ KODI_GUI_LISTITEM_HANDLE m_controlHandle;
+ AddonToKodiFuncTable_Addon* m_interface;
+ CAddonGUIControlBase* m_Window;
+
+private:
+ CAddonGUIControlBase() = delete;
+ CAddonGUIControlBase(const CAddonGUIControlBase&) = delete;
+ CAddonGUIControlBase& operator=(const CAddonGUIControlBase&) = delete;
+};
+
+class CListItem;
+
+//==============================================================================
+/// @addtogroup cpp_kodi_gui_windows_listitem
+/// @brief @cpp_class{ kodi::gui::CListItem }
+/// **Selectable window list item**\n
+/// The list item control is used for creating item lists in Kodi.
+///
+/// The with @ref ListItem.h "#include <kodi/gui/ListItem.h>" given
+/// class is used to create a item entry for a list on window and to support it's
+/// control.
+///
+class ATTR_DLL_LOCAL CListItem : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Class constructor with parameters.
+ ///
+ /// @param[in] label [opt] Item label
+ /// @param[in] label2 [opt] Second Item label (if needed)
+ /// @param[in] path [opt] Path to where item is defined
+ ///
+ CListItem(const std::string& label = "",
+ const std::string& label2 = "",
+ const std::string& path = "")
+ : CAddonGUIControlBase(nullptr)
+ {
+ m_controlHandle = m_interface->kodi_gui->listItem->create(m_interface->kodiBase, label.c_str(),
+ label2.c_str(), path.c_str());
+ }
+
+ /*
+ * Constructor used for parts given by list items from addon window
+ *
+ * Related to call of "std::shared_ptr<CListItem> kodi::gui::CWindow::GetListItem(int listPos)"
+ * Not needed for addon development itself
+ */
+ explicit CListItem(KODI_GUI_LISTITEM_HANDLE listItemHandle) : CAddonGUIControlBase(nullptr)
+ {
+ m_controlHandle = listItemHandle;
+ }
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Class destructor
+ ///
+ ~CListItem() override
+ {
+ m_interface->kodi_gui->listItem->destroy(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Returns the listitem label.
+ ///
+ /// @return Label of item
+ ///
+ std::string GetLabel()
+ {
+ std::string label;
+ char* ret = m_interface->kodi_gui->listItem->get_label(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Sets the listitem label.
+ ///
+ /// @param[in] label string or unicode - text string.
+ ///
+ void SetLabel(const std::string& label)
+ {
+ m_interface->kodi_gui->listItem->set_label(m_interface->kodiBase, m_controlHandle,
+ label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Returns the second listitem label.
+ ///
+ /// @return Second label of item
+ ///
+ std::string GetLabel2()
+ {
+ std::string label;
+ char* ret = m_interface->kodi_gui->listItem->get_label2(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Sets the listitem's label2.
+ ///
+ /// @param[in] label string or unicode - text string.
+ ///
+ void SetLabel2(const std::string& label)
+ {
+ m_interface->kodi_gui->listItem->set_label2(m_interface->kodiBase, m_controlHandle,
+ label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Sets the listitem's art
+ ///
+ /// @param[in] type Type of Art to set
+ /// - Some default art values (any string possible):
+ /// | value (type) | Type |
+ /// |:-------------:|:--------------------------------------------------|
+ /// | thumb | string - image filename
+ /// | poster | string - image filename
+ /// | banner | string - image filename
+ /// | fanart | string - image filename
+ /// | clearart | string - image filename
+ /// | clearlogo | string - image filename
+ /// | landscape | string - image filename
+ /// | icon | string - image filename
+ /// @return The url to use for Art
+ ///
+ std::string GetArt(const std::string& type)
+ {
+ std::string strReturn;
+ char* ret = m_interface->kodi_gui->listItem->get_art(m_interface->kodiBase, m_controlHandle,
+ type.c_str());
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ strReturn = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return strReturn;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Sets the listitem's art
+ ///
+ /// @param[in] type Type of Art to set
+ /// @param[in] url The url to use for Art
+ /// - Some default art values (any string possible):
+ /// | value (type) | Type |
+ /// |:-------------:|:--------------------------------------------------|
+ /// | thumb | string - image filename
+ /// | poster | string - image filename
+ /// | banner | string - image filename
+ /// | fanart | string - image filename
+ /// | clearart | string - image filename
+ /// | clearlogo | string - image filename
+ /// | landscape | string - image filename
+ /// | icon | string - image filename
+ ///
+ void SetArt(const std::string& type, const std::string& url)
+ {
+ m_interface->kodi_gui->listItem->set_art(m_interface->kodiBase, m_controlHandle, type.c_str(),
+ url.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Returns the path / filename of this listitem.
+ ///
+ /// @return Path string
+ ///
+ std::string GetPath()
+ {
+ std::string strReturn;
+ char* ret = m_interface->kodi_gui->listItem->get_path(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ strReturn = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return strReturn;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Sets the listitem's path.
+ ///
+ /// @param[in] path string or unicode - path, activated when item is clicked.
+ ///
+ /// @note You can use the above as keywords for arguments.
+ ///
+ void SetPath(const std::string& path)
+ {
+ m_interface->kodi_gui->listItem->set_path(m_interface->kodiBase, m_controlHandle, path.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Sets a listitem property, similar to an infolabel.
+ ///
+ /// @param[in] key string - property name.
+ /// @param[in] value string or unicode - value of property.
+ ///
+ /// @note Key is NOT case sensitive.
+ /// You can use the above as keywords for arguments and skip certain@n
+ /// optional arguments.\n
+ /// Once you use a keyword, all following arguments require the
+ /// keyword.
+ ///
+ /// Some of these are treated internally by Kodi, such as the
+ /// <b>'StartOffset'</b> property, which is the offset in seconds at which to
+ /// start playback of an item. Others may be used in the skin to add
+ /// extra information, such as <b>'WatchedCount'</b> for tvshow items
+ ///
+ void SetProperty(const std::string& key, const std::string& value)
+ {
+ m_interface->kodi_gui->listItem->set_property(m_interface->kodiBase, m_controlHandle,
+ key.c_str(), value.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Returns a listitem property as a string, similar to an infolabel.
+ ///
+ /// @param[in] key string - property name.
+ /// @return string - List item property
+ ///
+ /// @note Key is NOT case sensitive.\n
+ /// You can use the above as keywords for arguments and skip certain
+ /// optional arguments.\n
+ /// Once you use a keyword, all following arguments require the
+ /// keyword.
+ ///
+ std::string GetProperty(const std::string& key)
+ {
+ std::string label;
+ char* ret = m_interface->kodi_gui->listItem->get_property(m_interface->kodiBase,
+ m_controlHandle, key.c_str());
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief To control selection of item in list (also multiple selection,
+ /// in list on several items possible).
+ ///
+ /// @param[in] selected if true becomes set as selected
+ ///
+ void Select(bool selected)
+ {
+ m_interface->kodi_gui->listItem->select(m_interface->kodiBase, m_controlHandle, selected);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Returns the listitem's selected status.
+ ///
+ /// @return true if selected, otherwise false
+ ///
+ bool IsSelected()
+ {
+ return m_interface->kodi_gui->listItem->is_selected(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/Window.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/Window.h
new file mode 100644
index 0000000..e424c82
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/Window.h
@@ -0,0 +1,915 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+#include "../c-api/gui/window.h"
+#include "ListItem.h"
+#include "input/ActionIDs.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_window_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_gui_windows_window
+/// @brief **Library definition values**\n
+/// Additional values, structures and things that are used in the Window class.
+///
+/// ------------------------------------------------------------------------
+///
+/// @link cpp_kodi_gui_windows_window Go back to normal functions from CWindow@endlink
+///
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_windows_window_Defs
+/// @brief **Handler for addon-sided processing class**\n
+/// If the callback functions used by the window are not used directly in the
+/// @ref cpp_kodi_gui_windows_window "CWindow" class and are outside of it.
+///
+/// This value here corresponds to a <b>`void*`</b> and returns the address
+/// requested by the add-on for callbacks.
+///
+using ClientHandle = KODI_GUI_CLIENT_HANDLE;
+//------------------------------------------------------------------------------
+
+class CListItem;
+
+//==============================================================================
+/// @addtogroup cpp_kodi_gui_windows_window
+/// @brief @cpp_class{ kodi::gui::CWindow }
+/// **Main window control class**\n
+/// The addon uses its own skin xml file and displays it in Kodi using this class.
+///
+/// The with @ref Window.h "#include <kodi/gui/Window.h>"
+/// included file brings support to create a window or dialog on Kodi.
+///
+/// The add-on has to integrate its own @ref cpp_kodi_gui_windows_window_callbacks "callback functions"
+/// in order to process the necessary user access to its window.
+///
+///
+/// --------------------------------------------------------------------------
+///
+/// **Window header example:**
+/// ~~~~~~~~~~~~~{.xml}
+/// <?xml version="1.0" encoding="UTF-8"?>
+/// <window>
+/// <onload>RunScript(script.foobar)</onload>
+/// <onunload>SetProperty(foo,bar)</onunload>
+/// <defaultcontrol always="false">2</defaultcontrol>
+/// <menucontrol>9000</menucontrol>
+/// <backgroundcolor>0xff00ff00</backgroundcolor>
+/// <views>50,51,509,510</views>
+/// <visible>Window.IsActive(Home)</visible>
+/// <animation effect="fade" time="100">WindowOpen</animation>
+/// <animation effect="slide" end="0,576" time="100">WindowClose</animation>
+/// <zorder>1</zorder>
+/// <coordinates>
+/// <left>40</left>
+/// <top>50</top>
+/// <origin x="100" y="50">Window.IsActive(Home)</origin>
+/// </coordinates>
+/// <previouswindow>MyVideos</previouswindow>
+/// <controls>
+/// <control>
+/// </control>
+/// ....
+/// </controls>
+/// </window>
+/// ~~~~~~~~~~~~~
+///
+/// --------------------------------------------------------------------------
+///
+/// On functions defined input variable <b><tt>controlId</tt> (GUI control identifier)</b>
+/// is the on window.xml defined value behind type added with <tt><b>id="..."</b></tt> and
+/// used to identify for changes there and on callbacks.
+///
+/// ~~~~~~~~~~~~~{.xml}
+/// <control type="label" id="31">
+/// <description>Title Label</description>
+/// ...
+/// </control>
+/// <control type="progress" id="32">
+/// <description>progress control</description>
+/// ...
+/// </control>
+/// ~~~~~~~~~~~~~
+///
+///
+class ATTR_DLL_LOCAL CWindow : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Class constructor with needed values for window / dialog.
+ ///
+ /// Creates a new Window class.
+ ///
+ /// @param[in] xmlFilename XML file for the skin
+ /// @param[in] defaultSkin Default skin to use if needed not available
+ /// @param[in] asDialog Use window as dialog if set
+ /// @param[in] isMedia [opt] bool - if False, create a regular window.
+ /// if True, create a mediawindow. (default=false)
+ ///
+ /// @note <b>`isMedia`</b> value as true only usable for windows not for dialogs.
+ ///
+ CWindow(const std::string& xmlFilename,
+ const std::string& defaultSkin,
+ bool asDialog,
+ bool isMedia = false)
+ : CAddonGUIControlBase(nullptr)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->create(
+ m_interface->kodiBase, xmlFilename.c_str(), defaultSkin.c_str(), asDialog, isMedia);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL, "kodi::gui::CWindow can't create window class from Kodi !!!");
+ m_interface->kodi_gui->window->set_callbacks(m_interface->kodiBase, m_controlHandle, this,
+ CBOnInit, CBOnFocus, CBOnClick, CBOnAction,
+ CBGetContextButtons, CBOnContextButton);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup CWindow
+ /// @brief Class destructor.
+ ///
+ ~CWindow() override
+ {
+ if (m_controlHandle)
+ m_interface->kodi_gui->window->destroy(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Show this window.
+ ///
+ /// Shows this window by activating it, calling close() after it will activate
+ /// the current window again.
+ ///
+ /// @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 @ref DoModal() instead.
+ ///
+ /// @warning If used must be the class be global present until Kodi becomes
+ /// closed. The creation can be done 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.
+ ///
+ bool Show()
+ {
+ return m_interface->kodi_gui->window->show(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Closes this window.
+ ///
+ /// Closes this window by activating the old window.
+ /// @note The window is not deleted with this method.
+ ///
+ void Close() { m_interface->kodi_gui->window->close(m_interface->kodiBase, m_controlHandle); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Display this window until close() is called.
+ ///
+ void DoModal()
+ {
+ m_interface->kodi_gui->window->do_modal(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Gives the control with the supplied focus.
+ ///
+ /// @param[in] controlId On skin defined id of control
+ /// @return Return true if call and focus is successed, if false was something
+ /// failed to get needed skin parts
+ ///
+ bool SetFocusId(int controlId)
+ {
+ return m_interface->kodi_gui->window->set_focus_id(m_interface->kodiBase, m_controlHandle,
+ controlId);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Returns the id of the control which is focused.
+ ///
+ /// @return Focused control id
+ ///
+ int GetFocusId()
+ {
+ return m_interface->kodi_gui->window->get_focus_id(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To set the used label on given control id.
+ ///
+ /// @param[in] controlId Control id where label need to set
+ /// @param[in] label Label to use
+ ///
+ void SetControlLabel(int controlId, const std::string& label)
+ {
+ m_interface->kodi_gui->window->set_control_label(m_interface->kodiBase, m_controlHandle,
+ controlId, label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To set the visibility on given control id.
+ ///
+ /// @param[in] controlId Control id where visibility is changed
+ /// @param[in] visible Boolean value with `true` for visible, `false` for hidden
+ ///
+ void SetControlVisible(int controlId, bool visible)
+ {
+ m_interface->kodi_gui->window->set_control_visible(m_interface->kodiBase, m_controlHandle,
+ controlId, visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To set the selection on given control id.
+ ///
+ /// @param[in] controlId Control id where selection is changed
+ /// @param[in] selected Boolean value with `true` for selected, `false` for not
+ ///
+ void SetControlSelected(int controlId, bool selected)
+ {
+ m_interface->kodi_gui->window->set_control_selected(m_interface->kodiBase, m_controlHandle,
+ controlId, selected);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Sets a window property, similar to an infolabel.
+ ///
+ /// @param[in] key string - property name.
+ /// @param[in] value string or unicode - value of property.
+ ///
+ /// @note Key is NOT case sensitive. Setting value to an empty string is
+ /// equivalent to clearProperty(key).\n
+ /// You can use the above as keywords for arguments and skip certain
+ /// optional arguments.\n
+ /// Once you use a keyword, all following arguments require the keyword.
+ ///
+ void SetProperty(const std::string& key, const std::string& value)
+ {
+ m_interface->kodi_gui->window->set_property(m_interface->kodiBase, m_controlHandle, key.c_str(),
+ value.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Returns a window property as a string, similar to an infolabel.
+ ///
+ /// @param[in] key string - property name.
+ /// @return The property as string (if present)
+ ///
+ /// @note Key is NOT case sensitive. Setting value to an empty string is
+ /// equivalent to clearProperty(key).\n
+ /// You can use the above as keywords for arguments and skip certain
+ /// optional arguments.\n
+ /// Once you use a keyword, all following arguments require the keyword.
+ ///
+ std::string GetProperty(const std::string& key) const
+ {
+ std::string label;
+ char* ret = m_interface->kodi_gui->window->get_property(m_interface->kodiBase, m_controlHandle,
+ key.c_str());
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Sets a window property with integer value
+ ///
+ /// @param[in] key string - property name.
+ /// @param[in] value integer value to set
+ ///
+ void SetPropertyInt(const std::string& key, int value)
+ {
+ m_interface->kodi_gui->window->set_property_int(m_interface->kodiBase, m_controlHandle,
+ key.c_str(), value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Returns a window property with integer value
+ ///
+ /// @param[in] key string - property name.
+ /// @return integer value of property
+ ///
+ int GetPropertyInt(const std::string& key) const
+ {
+ return m_interface->kodi_gui->window->get_property_int(m_interface->kodiBase, m_controlHandle,
+ key.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Sets a window property with boolean value
+ ///
+ /// @param[in] key string - property name.
+ /// @param[in] value boolean value to set
+ ///
+ void SetPropertyBool(const std::string& key, bool value)
+ {
+ m_interface->kodi_gui->window->set_property_bool(m_interface->kodiBase, m_controlHandle,
+ key.c_str(), value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Returns a window property with boolean value
+ ///
+ /// @param[in] key string - property name.
+ /// @return boolean value of property
+ ///
+ bool GetPropertyBool(const std::string& key) const
+ {
+ return m_interface->kodi_gui->window->get_property_bool(m_interface->kodiBase, m_controlHandle,
+ key.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Sets a window property with double value
+ ///
+ /// @param[in] key string - property name.
+ /// @param[in] value double value to set
+ ///
+ void SetPropertyDouble(const std::string& key, double value)
+ {
+ m_interface->kodi_gui->window->set_property_double(m_interface->kodiBase, m_controlHandle,
+ key.c_str(), value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Returns a window property with double value
+ ///
+ /// @param[in] key string - property name.
+ /// @return double value of property
+ ///
+ double GetPropertyDouble(const std::string& key) const
+ {
+ return m_interface->kodi_gui->window->get_property_double(m_interface->kodiBase,
+ m_controlHandle, key.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Remove all present properties from window
+ ///
+ void ClearProperties()
+ {
+ m_interface->kodi_gui->window->clear_properties(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Clears the specific window property.
+ ///
+ /// @param[in] key string - property name.
+ ///
+ /// @note Key is NOT case sensitive. Equivalent to SetProperty(key, "")
+ /// You can use the above as keywords for arguments and skip certain
+ /// optional arguments.
+ /// Once you use a keyword, all following arguments require the
+ /// keyword.
+ ///
+ ///
+ ///-----------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ..
+ /// ClearProperty('Category')
+ /// ..
+ /// ~~~~~~~~~~~~~
+ ///
+ void ClearProperty(const std::string& key)
+ {
+ m_interface->kodi_gui->window->clear_property(m_interface->kodiBase, m_controlHandle,
+ key.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ /// @{
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Function delete all entries in integrated list.
+ ///
+ void ClearList()
+ {
+ m_interface->kodi_gui->window->clear_item_list(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To add a list item in the on window integrated list.
+ ///
+ /// @param[in] item List item to add
+ /// @param[in] itemPosition [opt] The position for item, default is on end
+ ///
+ void AddListItem(const std::shared_ptr<CListItem>& item, int itemPosition = -1)
+ {
+ m_interface->kodi_gui->window->add_list_item(m_interface->kodiBase, m_controlHandle,
+ item->m_controlHandle, itemPosition);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To add a list item based upon string in the on window integrated list.
+ ///
+ /// @param[in] item List item to add
+ /// @param[in] itemPosition [opt] The position for item, default is on end
+ ///
+ void AddListItem(const std::string& item, int itemPosition = -1)
+ {
+ m_interface->kodi_gui->window->add_list_item(
+ m_interface->kodiBase, m_controlHandle,
+ std::make_shared<kodi::gui::CListItem>(item)->m_controlHandle, itemPosition);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Remove list item on position.
+ ///
+ /// @param[in] itemPosition List position to remove
+ ///
+ void RemoveListItem(int itemPosition)
+ {
+ m_interface->kodi_gui->window->remove_list_item_from_position(m_interface->kodiBase,
+ m_controlHandle, itemPosition);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Remove item with given control class from list.
+ ///
+ /// @param[in] item List item control class to remove
+ ///
+ void RemoveListItem(const std::shared_ptr<CListItem>& item)
+ {
+ m_interface->kodi_gui->window->remove_list_item(m_interface->kodiBase, m_controlHandle,
+ item->m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To get list item control class on wanted position.
+ ///
+ /// @param[in] listPos Position from where control is needed
+ /// @return The list item control class or null if not found
+ ///
+ /// @warning Function returns a new generated **CListItem** class!
+ ///
+ std::shared_ptr<CListItem> GetListItem(int listPos)
+ {
+ KODI_GUI_LISTITEM_HANDLE handle = m_interface->kodi_gui->window->get_list_item(
+ m_interface->kodiBase, m_controlHandle, listPos);
+ if (!handle)
+ return std::shared_ptr<CListItem>();
+
+ return std::make_shared<kodi::gui::CListItem>(handle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To set position of selected part in list.
+ ///
+ /// @param[in] listPos Position to use
+ ///
+ void SetCurrentListPosition(int listPos)
+ {
+ m_interface->kodi_gui->window->set_current_list_position(m_interface->kodiBase, m_controlHandle,
+ listPos);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To get current selected position in list
+ ///
+ /// @return Current list position
+ ///
+ int GetCurrentListPosition()
+ {
+ return m_interface->kodi_gui->window->get_current_list_position(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To get the amount of entries in the list.
+ ///
+ /// @return Size of in window integrated control class
+ ///
+ int GetListSize()
+ {
+ return m_interface->kodi_gui->window->get_list_size(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Sets a container property, similar to an infolabel.
+ ///
+ /// @param[in] key string - property name.
+ /// @param[in] value string or unicode - value of property.
+ ///
+ /// @note Key is NOT case sensitive.\n
+ /// You can use the above as keywords for arguments and skip certain
+ /// optional arguments.\n
+ /// Once you use a keyword, all following arguments require the keyword.
+ ///
+ void SetContainerProperty(const std::string& key, const std::string& value)
+ {
+ m_interface->kodi_gui->window->set_container_property(m_interface->kodiBase, m_controlHandle,
+ key.c_str(), value.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Sets the content type of the container.
+ ///
+ /// @param[in] value string or unicode - content value.
+ ///
+ /// __Available content types__
+ /// | Name | Media |
+ /// |:-----------:|:-----------------------------------------|
+ /// | actors | Videos
+ /// | addons | Addons, Music, Pictures, Programs, Videos
+ /// | albums | Music, Videos
+ /// | artists | Music, Videos
+ /// | countries | Music, Videos
+ /// | directors | Videos
+ /// | files | Music, Videos
+ /// | games | Games
+ /// | genres | Music, Videos
+ /// | images | Pictures
+ /// | mixed | Music, Videos
+ /// | movies | Videos
+ /// | Musicvideos | Music, Videos
+ /// | playlists | Music, Videos
+ /// | seasons | Videos
+ /// | sets | Videos
+ /// | songs | Music
+ /// | studios | Music, Videos
+ /// | tags | Music, Videos
+ /// | tvshows | Videos
+ /// | videos | Videos
+ /// | years | Music, Videos
+ ///
+ void SetContainerContent(const std::string& value)
+ {
+ m_interface->kodi_gui->window->set_container_content(m_interface->kodiBase, m_controlHandle,
+ value.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Get the id of the currently visible container.
+ ///
+ /// @return currently visible container id
+ ///
+ int GetCurrentContainerId()
+ {
+ return m_interface->kodi_gui->window->get_current_container_id(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+ /// @}
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief To inform Kodi that it need to render region new.
+ ///
+ void MarkDirtyRegion()
+ {
+ return m_interface->kodi_gui->window->mark_dirty_region(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_gui_windows_window_callbacks Callback functions from Kodi to add-on
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @{
+ /// @brief <b>GUI window callback functions.</b>\n
+ /// Functions to handle control callbacks from Kodi
+ ///
+ /// ------------------------------------------------------------------------
+ ///
+ /// @link cpp_kodi_gui_windows_window Go back to normal functions from CWindow@endlink
+ //
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window_callbacks
+ /// @brief OnInit method.
+ ///
+ /// @return Return true if initialize was done successful
+ ///
+ ///
+ virtual bool OnInit() { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window_callbacks
+ /// @brief OnFocus method.
+ ///
+ /// @param[in] controlId GUI control identifier
+ /// @return Return true if focus condition was handled there or false to handle
+ /// them by Kodi itself
+ ///
+ ///
+ virtual bool OnFocus(int controlId) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window_callbacks
+ /// @brief OnClick method.
+ ///
+ /// @param[in] controlId GUI control identifier
+ /// @return Return true if click was handled there or false to handle them by
+ /// Kodi itself
+ ///
+ ///
+ virtual bool OnClick(int controlId) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window_callbacks
+ /// @brief OnAction method.
+ ///
+ /// @param[in] actionId The action id to perform, see
+ /// @ref kodi_key_action_ids to get list of
+ /// them
+ /// @return Return true if action was handled there
+ /// or false to handle them by Kodi itself
+ ///
+ ///
+ /// This method will receive all actions that the main program will send
+ /// to this window.
+ ///
+ /// @note
+ /// - By default, only the @c ADDON_ACTION_PREVIOUS_MENU and @c ADDON_ACTION_NAV_BACK actions are handled.
+ /// - Overwrite this method to let your code handle all actions.
+ /// - Don't forget to capture @ref ADDON_ACTION_PREVIOUS_MENU or @ref ADDON_ACTION_NAV_BACK, else the user can't close this window.
+ ///
+ ///
+ ///----------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ..
+ /// // Window used with parent / child way
+ /// bool cYOUR_CLASS::OnAction(ADDON_ACTION actionId)
+ /// {
+ /// switch (action)
+ /// {
+ /// case ADDON_ACTION_PREVIOUS_MENU:
+ /// case ADDON_ACTION_NAV_BACK:
+ /// printf("action received: previous");
+ /// Close();
+ /// return true;
+ /// case ADDON_ACTION_SHOW_INFO:
+ /// printf("action received: show info");
+ /// break;
+ /// case ADDON_ACTION_STOP:
+ /// printf("action received: stop");
+ /// break;
+ /// case ADDON_ACTION_PAUSE:
+ /// printf("action received: pause");
+ /// break;
+ /// default:
+ /// break;
+ /// }
+ /// return false;
+ /// }
+ /// ..
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual bool OnAction(ADDON_ACTION actionId)
+ {
+ switch (actionId)
+ {
+ case ADDON_ACTION_PREVIOUS_MENU:
+ case ADDON_ACTION_NAV_BACK:
+ Close();
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window_callbacks
+ /// @brief Get context menu buttons for list entry.
+ ///
+ /// @param[in] itemNumber Selected list item entry
+ /// @param[in] buttons List where context menus becomes added with his
+ /// identifier and name
+ ///
+ virtual void GetContextButtons(int itemNumber,
+ std::vector<std::pair<unsigned int, std::string>>& buttons)
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window_callbacks
+ /// @brief Called after selection in context menu.
+ ///
+ /// @param[in] itemNumber Selected list item entry
+ /// @param[in] button The pressed button id
+ /// @return true if handled, otherwise false
+ ///
+ virtual bool OnContextButton(int itemNumber, unsigned int button) { return false; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window_callbacks
+ /// @brief **Set independent callbacks**
+ ///
+ /// If the class is used independent (with "new CWindow") and
+ /// not as parent (with \"cCLASS_own : public @ref cpp_kodi_gui_windows_window "kodi::gui::CWindow"\") from own must be the
+ /// callback from Kodi to add-on overdriven with own functions!
+ ///
+ /// @param[in] cbhdl The pointer to own handle data structure / class
+ /// @param[in] CBOnInit Own defined window init function
+ /// @param[in] CBOnFocus Own defined focus function
+ /// @param[in] CBOnClick Own defined click function
+ /// @param[in] CBOnAction Own defined action function
+ /// @param[in] CBGetContextButtons [opt] To get context menu entries for
+ /// lists function
+ /// @param[in] CBOnContextButton [opt] Used context menu entry function
+ ///
+ ///
+ ///----------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// ...
+ ///
+ /// bool OnInit(kodi::gui::ClientHandle cbhdl)
+ /// {
+ /// ...
+ /// return true;
+ /// }
+ ///
+ /// bool OnFocus(kodi::gui::ClientHandle cbhdl, int controlId)
+ /// {
+ /// ...
+ /// return true;
+ /// }
+ ///
+ /// bool OnClick(kodi::gui::ClientHandle cbhdl, int controlId)
+ /// {
+ /// ...
+ /// return true;
+ /// }
+ ///
+ /// bool OnAction(kodi::gui::ClientHandle cbhdl, ADDON_ACTION actionId)
+ /// {
+ /// ...
+ /// return true;
+ /// }
+ ///
+ /// ...
+ /// // Somewhere where you create the window
+ /// CWindow myWindow = new CWindow;
+ /// myWindow->SetIndependentCallbacks(myWindow, OnInit, OnFocus, OnClick, OnAction);
+ /// ...
+ /// ~~~~~~~~~~~~~
+ ///
+ void SetIndependentCallbacks(kodi::gui::ClientHandle cbhdl,
+ bool (*CBOnInit)(kodi::gui::ClientHandle cbhdl),
+ bool (*CBOnFocus)(kodi::gui::ClientHandle cbhdl, int controlId),
+ bool (*CBOnClick)(kodi::gui::ClientHandle cbhdl, int controlId),
+ bool (*CBOnAction)(kodi::gui::ClientHandle cbhdl,
+ ADDON_ACTION actionId),
+ void (*CBGetContextButtons)(kodi::gui::ClientHandle cbhdl,
+ int itemNumber,
+ gui_context_menu_pair* buttons,
+ unsigned int* size) = nullptr,
+ bool (*CBOnContextButton)(kodi::gui::ClientHandle cbhdl,
+ int itemNumber,
+ unsigned int button) = nullptr)
+ {
+ if (!cbhdl || !CBOnInit || !CBOnFocus || !CBOnClick || !CBOnAction)
+ {
+ kodi::Log(ADDON_LOG_FATAL, "kodi::gui::CWindow::%s called with nullptr !!!", __FUNCTION__);
+ return;
+ }
+
+ m_interface->kodi_gui->window->set_callbacks(m_interface->kodiBase, m_controlHandle, cbhdl,
+ CBOnInit, CBOnFocus, CBOnClick, CBOnAction,
+ CBGetContextButtons, CBOnContextButton);
+ }
+ //----------------------------------------------------------------------------
+ /// @}
+
+private:
+ static bool CBOnInit(KODI_GUI_CLIENT_HANDLE cbhdl)
+ {
+ return static_cast<CWindow*>(cbhdl)->OnInit();
+ }
+
+ static bool CBOnFocus(KODI_GUI_CLIENT_HANDLE cbhdl, int controlId)
+ {
+ return static_cast<CWindow*>(cbhdl)->OnFocus(controlId);
+ }
+
+ static bool CBOnClick(KODI_GUI_CLIENT_HANDLE cbhdl, int controlId)
+ {
+ return static_cast<CWindow*>(cbhdl)->OnClick(controlId);
+ }
+
+ static bool CBOnAction(KODI_GUI_CLIENT_HANDLE cbhdl, ADDON_ACTION actionId)
+ {
+ return static_cast<CWindow*>(cbhdl)->OnAction(actionId);
+ }
+
+ static void CBGetContextButtons(KODI_GUI_CLIENT_HANDLE cbhdl,
+ int itemNumber,
+ gui_context_menu_pair* buttons,
+ unsigned int* size)
+ {
+ std::vector<std::pair<unsigned int, std::string>> buttonList;
+ static_cast<CWindow*>(cbhdl)->GetContextButtons(itemNumber, buttonList);
+ if (!buttonList.empty())
+ {
+ unsigned int presentSize = static_cast<unsigned int>(buttonList.size());
+ if (presentSize > *size)
+ kodi::Log(ADDON_LOG_WARNING, "GetContextButtons: More as allowed '%i' entries present!",
+ *size);
+ else
+ *size = presentSize;
+ for (unsigned int i = 0; i < *size; ++i)
+ {
+ buttons[i].id = buttonList[i].first;
+ strncpy(buttons[i].name, buttonList[i].second.c_str(), ADDON_MAX_CONTEXT_ENTRY_NAME_LENGTH);
+ }
+ }
+ }
+
+ static bool CBOnContextButton(KODI_GUI_CLIENT_HANDLE cbhdl, int itemNumber, unsigned int button)
+ {
+ return static_cast<CWindow*>(cbhdl)->OnContextButton(itemNumber, button);
+ }
+};
+
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Button.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Button.h
new file mode 100644
index 0000000..a34d44b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Button.h
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/button.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CButton Control Button
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CButton }
+/// **Standard push button control for window**\n
+/// The button control is used for creating push buttons in Kodi.
+///
+/// You can choose the position, size, and look of the button, as well as
+/// choosing what action(s) should be performed when pushed.
+///
+/// It has the header @ref Button.h "#include <kodi/gui/controls/Button.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref skin_Button_control "button control"
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CButton : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CButton(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_button(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL, "kodi::gui::CButton can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Destructor.
+ ///
+ ~CButton() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_button->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Set's the control's enabled/disabled state.
+ ///
+ /// @param[in] enabled If true enabled, otherwise disabled
+ ///
+ void SetEnabled(bool enabled)
+ {
+ m_interface->kodi_gui->control_button->set_enabled(m_interface->kodiBase, m_controlHandle,
+ enabled);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief To set the text string on button.
+ ///
+ /// @param[in] label Text to show
+ ///
+ void SetLabel(const std::string& label)
+ {
+ m_interface->kodi_gui->control_button->set_label(m_interface->kodiBase, m_controlHandle,
+ label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Get the used text from button.
+ ///
+ /// @return Text shown
+ ///
+ std::string GetLabel() const
+ {
+ std::string label;
+ char* ret =
+ m_interface->kodi_gui->control_button->get_label(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief If two labels are used for button becomes it set with them.
+ ///
+ /// @param[in] label Text for second label
+ ///
+ void SetLabel2(const std::string& label)
+ {
+ m_interface->kodi_gui->control_button->set_label2(m_interface->kodiBase, m_controlHandle,
+ label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Get the second label if present.
+ ///
+ /// @return Second label
+ ///
+ std::string GetLabel2() const
+ {
+ std::string label;
+ char* ret =
+ m_interface->kodi_gui->control_button->get_label2(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/CMakeLists.txt
new file mode 100644
index 0000000..bc21108
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ Button.h
+ Edit.h
+ FadeLabel.h
+ Image.h
+ Label.h
+ Progress.h
+ RadioButton.h
+ Rendering.h
+ SettingsSlider.h
+ Slider.h
+ Spin.h
+ TextBox.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_gui_controls)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Edit.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Edit.h
new file mode 100644
index 0000000..334dbc3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Edit.h
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/edit.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CEdit Control Edit
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CEdit }
+/// **Editable window text control used as an input control for the osd keyboard
+/// and other input fields**\n
+/// The edit control allows a user to input text in Kodi.
+///
+/// You can choose the font, size, colour, location and header of the text to be
+/// displayed.
+///
+/// It has the header @ref Edit.h "#include <kodi/gui/controls/Edit.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin partfor a @ref skin_Edit_control "edit control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+
+//==============================================================================
+// see gui/definition.h for use of group "cpp_kodi_gui_windows_controls_CEdit_Defs"
+///
+/// @defgroup cpp_kodi_gui_windows_controls_CEdit_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_gui_windows_controls_CEdit
+/// @brief **Library definition values**
+///
+
+class ATTR_DLL_LOCAL CEdit : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CEdit(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_edit(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::control::CEdit can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Destructor.
+ ///
+ ~CEdit() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_edit->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Set's the control's enabled/disabled state.
+ ///
+ /// @param[in] enabled If true enabled, otherwise disabled
+ ///
+ void SetEnabled(bool enabled)
+ {
+ m_interface->kodi_gui->control_edit->set_enabled(m_interface->kodiBase, m_controlHandle,
+ enabled);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief To set the text string on edit control.
+ ///
+ /// @param[in] label Text to show
+ ///
+ void SetLabel(const std::string& label)
+ {
+ m_interface->kodi_gui->control_edit->set_label(m_interface->kodiBase, m_controlHandle,
+ label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Returns the text heading for this edit control.
+ ///
+ /// @return Heading text
+ ///
+ std::string GetLabel() const
+ {
+ std::string label;
+ char* ret =
+ m_interface->kodi_gui->control_edit->get_label(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Set's text heading for this edit control.
+ ///
+ /// @param[in] text string or unicode - text string.
+ ///
+ void SetText(const std::string& text)
+ {
+ m_interface->kodi_gui->control_edit->set_text(m_interface->kodiBase, m_controlHandle,
+ text.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Returns the text value for this edit control.
+ ///
+ /// @return Text value of control
+ ///
+ std::string GetText() const
+ {
+ std::string text;
+ char* ret =
+ m_interface->kodi_gui->control_edit->get_text(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ text = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return text;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Set the cursor position on text.
+ ///
+ /// @param[in] position The position to set
+ ///
+ void SetCursorPosition(unsigned int position)
+ {
+ m_interface->kodi_gui->control_edit->set_cursor_position(m_interface->kodiBase, m_controlHandle,
+ position);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief To get current cursor position on text field.
+ ///
+ /// @return The current cursor position
+ ///
+ unsigned int GetCursorPosition()
+ {
+ return m_interface->kodi_gui->control_edit->get_cursor_position(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief To set field input type which are defined on @ref AddonGUIInputType.
+ ///
+ /// @param[in] type The @ref AddonGUIInputType "Add-on input type" to use
+ /// @param[in] heading The heading text for related keyboard dialog
+ ///
+ void SetInputType(AddonGUIInputType type, const std::string& heading)
+ {
+ m_interface->kodi_gui->control_edit->set_input_type(m_interface->kodiBase, m_controlHandle,
+ static_cast<int>(type), heading.c_str());
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/FadeLabel.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/FadeLabel.h
new file mode 100644
index 0000000..2a888a6
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/FadeLabel.h
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/fade_label.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CFadeLabel Control Fade Label
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CFadeLabel }
+/// **Window control used to show multiple pieces of text in the same position,
+/// by fading from one to the other**\n
+/// The fade label control is used for displaying multiple pieces of text in
+/// the same space in Kodi.
+///
+/// You can choose the font, size, colour, location and contents of the text to
+/// be displayed. The first piece of information to display fades in over 50
+/// frames, then scrolls off to the left. Once it is finished scrolling off
+/// screen, the second piece of information fades in and the process repeats.
+/// A fade label control is not supported in a list container.
+///
+/// It has the header @ref FadeLabel.h "#include <kodi/gui/controls/FadeLabel.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Fade_Label_Control "fade label control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CFadeLabel : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CFadeLabel(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_fade_label(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CFadeLabel can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief Destructor.
+ ///
+ ~CFadeLabel() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_fade_label->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief To add additional text string on fade label.
+ ///
+ /// @param[in] label Text to show
+ ///
+ void AddLabel(const std::string& label)
+ {
+ m_interface->kodi_gui->control_fade_label->add_label(m_interface->kodiBase, m_controlHandle,
+ label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief Get the used text from button.
+ ///
+ /// @return Text shown
+ ///
+ std::string GetLabel() const
+ {
+ std::string label;
+ char* ret = m_interface->kodi_gui->control_fade_label->get_label(m_interface->kodiBase,
+ m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief To enable or disable scrolling on fade label.
+ ///
+ /// @param[in] scroll To enable scrolling set to true, otherwise is disabled
+ ///
+ void SetScrolling(bool scroll)
+ {
+ m_interface->kodi_gui->control_fade_label->set_scrolling(m_interface->kodiBase, m_controlHandle,
+ scroll);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief To reset al inserted labels.
+ ///
+ void Reset()
+ {
+ m_interface->kodi_gui->control_fade_label->reset(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Image.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Image.h
new file mode 100644
index 0000000..842d32a
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Image.h
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/image.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CImage Control Image
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CImage }
+/// **Window control used to show an image.**\n
+/// The image control is used for displaying images in Kodi. You can choose
+/// the position, size, transparency and contents of the image to be displayed.
+///
+/// It has the header @ref Image.h "#include <kodi/gui/controls/Image.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Image_Control "image control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CImage : public CAddonGUIControlBase
+{
+public:
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CImage
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CImage(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_image(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CImage can't create control class from Kodi !!!");
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CImage
+ /// @brief Destructor.
+ ///
+ ~CImage() override = default;
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CImage
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_image->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CImage
+ /// @brief To set the filename used on image control.
+ ///
+ /// @param[in] filename Image file to use
+ /// @param[in] useCache To define storage of image, default is in cache, if
+ /// false becomes it loaded always on changes again
+ ///
+ void SetFileName(const std::string& filename, bool useCache = true)
+ {
+ m_interface->kodi_gui->control_image->set_filename(m_interface->kodiBase, m_controlHandle,
+ filename.c_str(), useCache);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CImage
+ /// @brief To set set the diffuse color on image.
+ ///
+ /// @param[in] colorDiffuse Color to use for diffuse
+ ///
+ void SetColorDiffuse(uint32_t colorDiffuse)
+ {
+ m_interface->kodi_gui->control_image->set_color_diffuse(m_interface->kodiBase, m_controlHandle,
+ colorDiffuse);
+ }
+ //--------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Label.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Label.h
new file mode 100644
index 0000000..fbc35c3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Label.h
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/label.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CLabel Control Label
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CLabel }
+/// **Window control used to show some lines of text**\n
+/// The label control is used for displaying text in Kodi. You can choose
+/// the font, size, colour, location and contents of the text to be displayed.
+///
+/// It has the header @ref Label.h "#include <kodi/gui/controls/Label.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Label_Control "label control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CLabel : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CLabel
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CLabel(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_label(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CLabel can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CLabel
+ /// @brief Destructor.
+ ///
+ ~CLabel() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CLabel
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_label->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CLabel
+ /// @brief To set the text string on label.
+ ///
+ /// @param[in] text Text to show
+ ///
+ void SetLabel(const std::string& text)
+ {
+ m_interface->kodi_gui->control_label->set_label(m_interface->kodiBase, m_controlHandle,
+ text.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CLabel
+ /// @brief Get the used text from control.
+ ///
+ /// @return Used text on label control
+ ///
+ std::string GetLabel() const
+ {
+ std::string label;
+ char* ret =
+ m_interface->kodi_gui->control_label->get_label(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Progress.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Progress.h
new file mode 100644
index 0000000..8393b1d
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Progress.h
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/progress.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CProgress Control Progress
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CProgress }
+/// **Window control to show the progress of a particular operation**\n
+/// The progress control is used to show the progress of an item that may take
+/// a long time, or to show how far through a movie you are.
+///
+/// You can choose the position, size, and look of the progress control.
+///
+/// It has the header @ref Progress.h "#include <kodi/gui/controls/Progress.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Progress_Control "progress control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CProgress : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CProgress(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_progress(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CProgress can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief Destructor.
+ ///
+ ~CProgress() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_progress->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief To set Percent position of control.
+ ///
+ /// @param[in] percent The percent position to use
+ ///
+ void SetPercentage(float percent)
+ {
+ m_interface->kodi_gui->control_progress->set_percentage(m_interface->kodiBase, m_controlHandle,
+ percent);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief Get the active percent position of progress bar.
+ ///
+ /// @return Progress position as percent
+ ///
+ float GetPercentage() const
+ {
+ return m_interface->kodi_gui->control_progress->get_percentage(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/RadioButton.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/RadioButton.h
new file mode 100644
index 0000000..2d70fdc
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/RadioButton.h
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/radio_button.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CRadioButton Control Radio Button
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CRadioButton }
+/// **Window control for a radio button (as used for on/off settings)**\n
+/// The radio button control is used for creating push button on/off settings
+/// in Kodi.
+///
+/// You can choose the position, size, and look of the button. When the user
+/// clicks on the radio button, the state will change, toggling the extra
+/// textures (textureradioon and textureradiooff). Used for settings
+/// controls.
+///
+/// It has the header @ref RadioButton.h "#include <kodi/gui/controls/RadioButton.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Radio_button_control "radio button control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+///
+/// --------------------------------------------------------------------------
+/// **Example:**
+/// ~~~~~~~~~~~~cpp
+/// #include <kodi/gui/Window.h>
+///
+/// #define MY_RADIO_BUTTON_CONTROL 1
+///
+/// class CMyWindow : public kodi::gui::CWindow
+/// {
+/// public:
+/// CMyWindow()
+///
+/// void ShowWindow();
+///
+/// bool OnInit() override;
+/// bool OnClick(int controlId) override;
+///
+/// private:
+/// kodi::gui::controls::CSpin m_myRadioButtonControl;
+/// };
+///
+/// CMyWindow::CMyWindow()
+/// : kodi::gui::CWindow("my_skin.xml", "skin.estuary", true, false),
+/// m_myRadioButtonControl(this, MY_RADIO_BUTTON_CONTROL)
+/// {
+/// }
+///
+/// void CMyWindow::ShowWindow()
+/// {
+/// kodi::gui::CWindow::DoModal();
+/// }
+///
+/// bool CMyWindow::OnInit()
+/// {
+/// m_myRadioButtonControl.SetSelected(false); // can also on skin set to default
+/// return true;
+/// }
+///
+/// bool CMyWindow::OnClick(int controlId)
+/// {
+/// if (controlId == MY_RADIO_BUTTON_CONTROL)
+/// {
+/// bool selected = m_myRadioButtonControl.IsSelected();
+/// ...
+/// }
+/// return true;
+/// }
+/// return false;
+/// }
+/// ~~~~~~~~~~~~
+///
+class ATTR_DLL_LOCAL CRadioButton : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CRadioButton(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_radio_button(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CRadioButton can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Destructor.
+ ///
+ ~CRadioButton() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton.
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_radio_button->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Set's the control's enabled/disabled state.
+ ///
+ /// @param[in] enabled If true enabled, otherwise disabled
+ ///
+ void SetEnabled(bool enabled)
+ {
+ m_interface->kodi_gui->control_radio_button->set_enabled(m_interface->kodiBase, m_controlHandle,
+ enabled);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief To set the text string on radio button.
+ ///
+ /// @param[in] label Text to show
+ ///
+ void SetLabel(const std::string& label)
+ {
+ m_interface->kodi_gui->control_radio_button->set_label(m_interface->kodiBase, m_controlHandle,
+ label.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Get the used text from control.
+ ///
+ /// @return Text shown
+ ///
+ std::string GetLabel() const
+ {
+ std::string label;
+ char* ret = m_interface->kodi_gui->control_radio_button->get_label(m_interface->kodiBase,
+ m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return label;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief To set radio button condition to on or off.
+ ///
+ /// @param[in] selected true set radio button to selection on, otherwise off
+ ///
+ void SetSelected(bool selected)
+ {
+ m_interface->kodi_gui->control_radio_button->set_selected(m_interface->kodiBase,
+ m_controlHandle, selected);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Get the current selected condition of radio button.
+ ///
+ /// @return Selected condition
+ ///
+ bool IsSelected() const
+ {
+ return m_interface->kodi_gui->control_radio_button->is_selected(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Rendering.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Rendering.h
new file mode 100644
index 0000000..afaf76b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Rendering.h
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/rendering.h"
+#include "../Window.h"
+#include "../renderHelper.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CRendering Control Rendering
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CRendering }
+/// **Window control for rendering own parts**\n
+/// This rendering control is used when own parts are needed.
+///
+/// You have the control over them to render direct OpenGL or DirectX content
+/// to the screen set by the size of them.
+///
+/// Alternative can be the virtual functions from t his been ignored if the
+/// callbacks are defined by the @ref CRendering_SetIndependentCallbacks
+/// function and class is used as single and not as a parent class.
+///
+/// It has the header @ref Rendering.h "#include <kodi/gui/controls/Rendering.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Addon_Rendering_control "rendering control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CRendering : public CAddonGUIControlBase
+{
+public:
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CRendering(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_render_addon(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (m_controlHandle)
+ m_interface->kodi_gui->control_rendering->set_callbacks(m_interface->kodiBase,
+ m_controlHandle, this, OnCreateCB,
+ OnRenderCB, OnStopCB, OnDirtyCB);
+ else
+ kodi::Log(ADDON_LOG_FATAL, "kodi::gui::controls::%s can't create control class from Kodi !!!",
+ __FUNCTION__);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief Destructor.
+ ///
+ ~CRendering() override
+ {
+ m_interface->kodi_gui->control_rendering->destroy(m_interface->kodiBase, m_controlHandle);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief To create rendering control on Add-on.
+ ///
+ /// Function creates the needed rendering control for Kodi which becomes
+ /// handled and processed from Add-on
+ ///
+ /// @note This is callback function from Kodi to Add-on and not to use
+ /// for calls from add-on to this function.
+ ///
+ /// @param[in] x Horizontal position
+ /// @param[in] y Vertical position
+ /// @param[in] w Width of control
+ /// @param[in] h Height of control
+ /// @param[in] device The device to use. For OpenGL is empty on Direct X is
+ /// the needed device send.
+ /// @return Add-on needs to return true if successed, otherwise false.
+ ///
+ /// @note The @ref kodi::HardwareContext is basically a simple pointer which
+ /// has to be changed to the desired format at the corresponding places using
+ /// <b>`static_cast<...>(...)`</b>.
+ ///
+ virtual bool Create(int x, int y, int w, int h, kodi::HardwareContext device) { return false; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief Render process call from Kodi.
+ ///
+ /// @note This is callback function from Kodi to Add-on and not to use for
+ /// calls from add-on to this function.
+ ///
+ virtual void Render() {}
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief Call from Kodi to stop rendering process.
+ ///
+ /// @note This is callback function from Kodi to Add-on and not to use
+ /// for calls from add-on to this function.
+ ///
+ virtual void Stop() {}
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief Call from Kodi where add-on becomes asked about dirty rendering
+ /// region.
+ ///
+ /// @note This is callback function from Kodi to Add-on and not to use
+ /// for calls from add-on to this function.
+ ///
+ /// @return True if a render region is dirty and need rendering.
+ ///
+ virtual bool Dirty() { return false; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @anchor CRendering_SetIndependentCallbacks
+ /// @brief If the class is used independent (with "new CRendering")
+ /// and not as parent (with "cCLASS_own : CRendering") from own must
+ /// be the callback from Kodi to add-on overdriven with own functions!
+ ///
+ /// @param[in] cbhdl Addon related class point where becomes given as value on
+ /// related functions.
+ /// @param[in] CBCreate External creation function pointer, see also @ref Create
+ /// about related values
+ /// @param[in] CBRender External render function pointer, see also @ref Render
+ /// about related values
+ /// @param[in] CBStop External stop function pointer, see also @ref Stop
+ /// about related values
+ /// @param[in] CBDirty External dirty function pointer, see also @ref Dirty
+ /// about related values
+ ///
+ void SetIndependentCallbacks(kodi::gui::ClientHandle cbhdl,
+ bool (*CBCreate)(kodi::gui::ClientHandle cbhdl,
+ int x,
+ int y,
+ int w,
+ int h,
+ kodi::HardwareContext device),
+ void (*CBRender)(kodi::gui::ClientHandle cbhdl),
+ void (*CBStop)(kodi::gui::ClientHandle cbhdl),
+ bool (*CBDirty)(kodi::gui::ClientHandle cbhdl))
+ {
+ if (!cbhdl || !CBCreate || !CBRender || !CBStop || !CBDirty)
+ {
+ kodi::Log(ADDON_LOG_ERROR, "kodi::gui::controls::%s called with nullptr !!!", __FUNCTION__);
+ return;
+ }
+
+ m_interface->kodi_gui->control_rendering->set_callbacks(
+ m_interface->kodiBase, m_controlHandle, cbhdl, CBCreate, CBRender, CBStop, CBDirty);
+ }
+ //--------------------------------------------------------------------------
+
+private:
+ /*
+ * Defined callback functions from Kodi to add-on, for use in parent / child system
+ * (is private)!
+ */
+ static bool OnCreateCB(
+ KODI_GUI_CLIENT_HANDLE cbhdl, int x, int y, int w, int h, ADDON_HARDWARE_CONTEXT device)
+ {
+ static_cast<CRendering*>(cbhdl)->m_renderHelper = kodi::gui::GetRenderHelper();
+ return static_cast<CRendering*>(cbhdl)->Create(x, y, w, h, device);
+ }
+
+ static void OnRenderCB(KODI_GUI_CLIENT_HANDLE cbhdl)
+ {
+ if (!static_cast<CRendering*>(cbhdl)->m_renderHelper)
+ return;
+ static_cast<CRendering*>(cbhdl)->m_renderHelper->Begin();
+ static_cast<CRendering*>(cbhdl)->Render();
+ static_cast<CRendering*>(cbhdl)->m_renderHelper->End();
+ }
+
+ static void OnStopCB(KODI_GUI_CLIENT_HANDLE cbhdl)
+ {
+ static_cast<CRendering*>(cbhdl)->Stop();
+ static_cast<CRendering*>(cbhdl)->m_renderHelper = nullptr;
+ }
+
+ static bool OnDirtyCB(KODI_GUI_CLIENT_HANDLE cbhdl)
+ {
+ return static_cast<CRendering*>(cbhdl)->Dirty();
+ }
+
+ std::shared_ptr<kodi::gui::IRenderHelper> m_renderHelper;
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/SettingsSlider.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/SettingsSlider.h
new file mode 100644
index 0000000..e1de9d0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/SettingsSlider.h
@@ -0,0 +1,314 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/settings_slider.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CSettingsSlider Control Settings Slider
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CSettingsSlider }
+/// **Window control for moveable slider with text name**\n
+/// The settings slider control is used in the settings screens for when an
+/// option is best specified on a sliding scale.
+///
+/// You can choose the position, size, and look of the slider control. It is
+/// basically a cross between the button control and a slider control. It has a
+/// label and focus and non focus textures, as well as a slider control on the
+/// right.
+///
+/// It has the header @ref SettingsSlider.h "#include <kodi/gui/controls/SettingsSlider.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Settings_Slider_Control "settings slider control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CSettingsSlider : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CSettingsSlider(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_settings_slider(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CSettingsSlider can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Destructor.
+ ///
+ ~CSettingsSlider() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_visible(m_interface->kodiBase,
+ m_controlHandle, visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Set's the control's enabled/disabled state.
+ ///
+ /// @param[in] enabled If true enabled, otherwise disabled
+ ///
+ void SetEnabled(bool enabled)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_enabled(m_interface->kodiBase,
+ m_controlHandle, enabled);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To set the text string on settings slider.
+ ///
+ /// @param[in] text Text to show
+ ///
+ void SetText(const std::string& text)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_text(m_interface->kodiBase, m_controlHandle,
+ text.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To reset slider on defaults.
+ ///
+ void Reset()
+ {
+ m_interface->kodi_gui->control_settings_slider->reset(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To set the the range as integer of slider, e.g. -10 is the slider
+ /// start and e.g. +10 is the from here defined position where it reach the
+ /// end.
+ ///
+ /// Ad default is the range from 0 to 100.
+ ///
+ /// The integer interval is as default 1 and can be changed with
+ /// @ref SetIntInterval.
+ ///
+ /// @param[in] start Integer start value
+ /// @param[in] end Integer end value
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetIntRange(int start, int end)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_int_range(m_interface->kodiBase,
+ m_controlHandle, start, end);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Set the slider position with the given integer value. The Range
+ /// must be defined with a call from @ref SetIntRange before.
+ ///
+ /// @param[in] value Position in range to set with integer
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetIntValue(int value)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_int_value(m_interface->kodiBase,
+ m_controlHandle, value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To get the current position as integer value.
+ ///
+ /// @return The position as integer
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ int GetIntValue() const
+ {
+ return m_interface->kodi_gui->control_settings_slider->get_int_value(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To set the interval steps of slider, as default is it 1. If it
+ /// becomes changed with this function will a step of the user with the
+ /// value fixed here be executed.
+ ///
+ /// @param[in] interval Intervall step to set.
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetIntInterval(int interval)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_int_interval(m_interface->kodiBase,
+ m_controlHandle, interval);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Sets the percent of the slider.
+ ///
+ /// @param[in] percent float - Percent value of slide
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetPercentage(float percent)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_percentage(m_interface->kodiBase,
+ m_controlHandle, percent);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Returns a float of the percent of the slider.
+ ///
+ /// @return float - Percent of slider
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ float GetPercentage() const
+ {
+ return m_interface->kodi_gui->control_settings_slider->get_percentage(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To set the the range as float of slider, e.g. -25.0 is the slider
+ /// start and e.g. +25.0 is the from here defined position where it reach
+ /// the end.
+ ///
+ /// As default is the range 0.0 to 1.0.
+ ///
+ /// The float interval is as default 0.1 and can be changed with
+ /// @ref SetFloatInterval.
+ ///
+ /// @param[in] start Integer start value
+ /// @param[in] end Integer end value
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetFloatRange(float start, float end)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_float_range(m_interface->kodiBase,
+ m_controlHandle, start, end);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Set the slider position with the given float value. The Range can
+ /// be defined with a call from @ref SetIntRange before, as default it
+ /// is 0.0 to 1.0.
+ ///
+ /// @param[in] value Position in range to set with float
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetFloatValue(float value)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_float_value(m_interface->kodiBase,
+ m_controlHandle, value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To get the current position as float value.
+ ///
+ /// @return The position as float
+ ///
+ float GetFloatValue() const
+ {
+ return m_interface->kodi_gui->control_settings_slider->get_float_value(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To set the interval steps of slider, as default is it 0.1 If it
+ /// becomes changed with this function will a step of the user with the
+ /// value fixed here be executed.
+ ///
+ /// @param[in] interval Intervall step to set.
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetFloatInterval(float interval)
+ {
+ m_interface->kodi_gui->control_settings_slider->set_float_interval(m_interface->kodiBase,
+ m_controlHandle, interval);
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Slider.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Slider.h
new file mode 100644
index 0000000..405cc65
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Slider.h
@@ -0,0 +1,326 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/slider.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CSlider Control Slider
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CSlider }
+/// **Window control for moveable slider**\n
+/// The slider control is used for things where a sliding bar best represents
+/// the operation at hand (such as a volume control or seek control).
+///
+/// You can choose the position, size, and look of the slider control.
+///
+/// It has the header @ref Slider.h "#include <kodi/gui/controls/Slider.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Slider_Control "slider control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CSlider : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CSlider(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_slider(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CSlider can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Destructor.
+ ///
+ ~CSlider() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_slider->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Set's the control's enabled/disabled state.
+ ///
+ /// @param[in] enabled If true enabled, otherwise disabled
+ ///
+ void SetEnabled(bool enabled)
+ {
+ m_interface->kodi_gui->control_slider->set_enabled(m_interface->kodiBase, m_controlHandle,
+ enabled);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief To reset slider on defaults.
+ ///
+ void Reset()
+ {
+ m_interface->kodi_gui->control_slider->reset(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief With GetDescription becomes a string value of position returned.
+ ///
+ /// @return Text string about current slider position
+ ///
+ /// The following are the text definition returned from this:
+ /// | Value | Without range selection | With range selection |
+ /// |:---------:|:------------------------|:-------------------------------|
+ /// | float | <c>%2.2f</c> | <c>[%2.2f, %2.2f]</c> |
+ /// | integer | <c>%i</c> | <c>[%i, %i]</c> |
+ /// | percent | <c>%i%%</c> | <c>[%i%%, %i%%]</c> |
+ ///
+ std::string GetDescription() const
+ {
+ std::string text;
+ char* ret = m_interface->kodi_gui->control_slider->get_description(m_interface->kodiBase,
+ m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ text = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return text;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief To set the the range as integer of slider, e.g. -10 is the slider
+ /// start and e.g. +10 is the from here defined position where it reach the
+ /// end.
+ ///
+ /// Ad default is the range from 0 to 100.
+ ///
+ /// The integer interval is as default 1 and can be changed with
+ /// @ref SetIntInterval.
+ ///
+ /// @param[in] start Integer start value
+ /// @param[in] end Integer end value
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only one
+ /// each can be used.
+ ///
+ void SetIntRange(int start, int end)
+ {
+ m_interface->kodi_gui->control_slider->set_int_range(m_interface->kodiBase, m_controlHandle,
+ start, end);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Set the slider position with the given integer value. The Range
+ /// must be defined with a call from @ref SetIntRange before.
+ ///
+ /// @param[in] value Position in range to set with integer
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only one
+ /// each can be used.
+ ///
+ void SetIntValue(int value)
+ {
+ m_interface->kodi_gui->control_slider->set_int_value(m_interface->kodiBase, m_controlHandle,
+ value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief To get the current position as integer value.
+ ///
+ /// @return The position as integer
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ int GetIntValue() const
+ {
+ return m_interface->kodi_gui->control_slider->get_int_value(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief To set the interval steps of slider, as default is it 1. If it
+ /// becomes changed with this function will a step of the user with the
+ /// value fixed here be executed.
+ ///
+ /// @param[in] interval Intervall step to set.
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only one
+ /// each can be used.
+ ///
+ void SetIntInterval(int interval)
+ {
+ m_interface->kodi_gui->control_slider->set_int_interval(m_interface->kodiBase, m_controlHandle,
+ interval);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Sets the percent of the slider.
+ ///
+ /// @param[in] percent float - Percent value of slide
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only one
+ /// each can be used.
+ ///
+ void SetPercentage(float percent)
+ {
+ m_interface->kodi_gui->control_slider->set_percentage(m_interface->kodiBase, m_controlHandle,
+ percent);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Returns a float of the percent of the slider.
+ ///
+ /// @return float - Percent of slider
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only one
+ /// each can be used.
+ ///
+ float GetPercentage() const
+ {
+ return m_interface->kodi_gui->control_slider->get_percentage(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief To set the the range as float of slider, e.g. -25.0 is the slider
+ /// start and e.g. +25.0 is the from here defined position where it reach
+ /// the end.
+ ///
+ /// As default is the range 0.0 to 1.0.
+ ///
+ /// The float interval is as default 0.1 and can be changed with
+ /// @ref SetFloatInterval.
+ ///
+ /// @param[in] start Integer start value
+ /// @param[in] end Integer end value
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetFloatRange(float start, float end)
+ {
+ m_interface->kodi_gui->control_slider->set_float_range(m_interface->kodiBase, m_controlHandle,
+ start, end);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Set the slider position with the given float value. The Range
+ /// can be defined with a call from @ref SetIntRange before, as default it
+ /// is 0.0 to 1.0.
+ ///
+ /// @param[in] value Position in range to set with float
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only one
+ /// each can be used.
+ ///
+ void SetFloatValue(float value)
+ {
+ m_interface->kodi_gui->control_slider->set_float_value(m_interface->kodiBase, m_controlHandle,
+ value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief To get the current position as float value.
+ ///
+ /// @return The position as float
+ ///
+ float GetFloatValue() const
+ {
+ return m_interface->kodi_gui->control_slider->get_float_value(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief To set the interval steps of slider, as default is it 0.1 If it
+ /// becomes changed with this function will a step of the user with the
+ /// value fixed here be executed.
+ ///
+ /// @param[in] interval Intervall step to set.
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used.
+ ///
+ void SetFloatInterval(float interval)
+ {
+ m_interface->kodi_gui->control_slider->set_float_interval(m_interface->kodiBase,
+ m_controlHandle, interval);
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Spin.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Spin.h
new file mode 100644
index 0000000..d0a7306
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Spin.h
@@ -0,0 +1,416 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/spin.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CSpin Control Spin
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CSpin }
+/// **Window control used for cycling up/down controls**\n
+/// The settings spin control is used in the settings screens for when a list
+/// of options can be chosen from using up/down arrows.
+///
+/// You can choose the position, size, and look of the spin control. It is
+/// basically a cross between the button control and a spin control. It has a
+/// label and focus and non focus textures, as well as a spin control on the
+/// right.
+///
+/// It has the header @ref Spin.h "#include <kodi/gui/controls/Spin.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Spin_Control "spin control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+/// --------------------------------------------------------------------------
+/// **Example:**
+/// ~~~~~~~~~~~~cpp
+/// #include <kodi/gui/Window.h>
+///
+/// #define MY_SPIN_CONTROL 1
+///
+/// class CMyWindow : public kodi::gui::CWindow
+/// {
+/// public:
+/// CMyWindow()
+///
+/// void ShowWindow();
+///
+/// bool OnInit() override;
+/// bool OnClick(int controlId) override;
+///
+/// private:
+/// kodi::gui::controls::CSpin m_mySpinControl;
+/// };
+///
+/// CMyWindow::CMyWindow()
+/// : kodi::gui::CWindow("my_skin.xml", "skin.estuary", true, false),
+/// m_mySpinControl(this, MY_SPIN_CONTROL)
+/// {
+/// }
+///
+/// void CMyWindow::ShowWindow()
+/// {
+/// kodi::gui::CWindow::DoModal();
+/// }
+///
+/// bool CMyWindow::OnInit()
+/// {
+/// m_mySpinControl.SetType(kodi::gui::controls::ADDON_SPIN_CONTROL_TYPE_INT);
+/// m_mySpinControl.SetIntRange(1, 80);
+/// return true;
+/// }
+///
+/// bool CMyWindow::OnClick(int controlId)
+/// {
+/// if (controlId == MY_SPIN_CONTROL)
+/// {
+/// int value = m_mySpinControl.GetIntValue();
+/// ...
+/// }
+/// return true;
+/// }
+/// return false;
+/// }
+/// ~~~~~~~~~~~~
+///
+
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_windows_controls_CSpin
+/// @anchor AddonGUISpinControlType
+/// @brief The values here defines the used value format for steps on
+/// spin control.
+///
+typedef enum AddonGUISpinControlType
+{
+ /// One spin step interpreted as integer
+ ADDON_SPIN_CONTROL_TYPE_INT = 1,
+ /// One spin step interpreted as floating point value
+ ADDON_SPIN_CONTROL_TYPE_FLOAT = 2,
+ /// One spin step interpreted as text string
+ ADDON_SPIN_CONTROL_TYPE_TEXT = 3,
+ /// One spin step interpreted as a page change value
+ ADDON_SPIN_CONTROL_TYPE_PAGE = 4
+} AddonGUISpinControlType;
+//------------------------------------------------------------------------------
+
+class ATTR_DLL_LOCAL CSpin : public CAddonGUIControlBase
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CSpin(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_spin(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CSpin can't create control class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Destructor.
+ ///
+ ~CSpin() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_spin->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Set's the control's enabled/disabled state.
+ ///
+ /// @param[in] enabled If true enabled, otherwise disabled
+ ///
+ void SetEnabled(bool enabled)
+ {
+ m_interface->kodi_gui->control_spin->set_enabled(m_interface->kodiBase, m_controlHandle,
+ enabled);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To set the text string on spin control.
+ ///
+ /// @param[in] text Text to show as name for spin
+ ///
+ void SetText(const std::string& text)
+ {
+ m_interface->kodi_gui->control_spin->set_text(m_interface->kodiBase, m_controlHandle,
+ text.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To reset spin control to defaults.
+ ///
+ void Reset()
+ {
+ m_interface->kodi_gui->control_spin->reset(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To set the with SpinControlType defined types of spin.
+ ///
+ /// @param[in] type The type to use
+ ///
+ /// @note See description of @ref AddonGUISpinControlType for available types.
+ ///
+ void SetType(AddonGUISpinControlType type)
+ {
+ m_interface->kodi_gui->control_spin->set_type(m_interface->kodiBase, m_controlHandle,
+ (int)type);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To add a label entry in spin defined with a value as string.
+ ///
+ /// Format must be set to @ref ADDON_SPIN_CONTROL_TYPE_TEXT to use this function.
+ ///
+ /// @param[in] label Label string to view on skin
+ /// @param[in] value String value to use for selection of them
+ ///
+ void AddLabel(const std::string& label, const std::string& value)
+ {
+ m_interface->kodi_gui->control_spin->add_string_label(m_interface->kodiBase, m_controlHandle,
+ label.c_str(), value.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To add a label entry in spin defined with a value as integer.
+ ///
+ /// Format must be set to @ref ADDON_SPIN_CONTROL_TYPE_INT to use this function.
+ ///
+ /// @param[in] label Label string to view on skin
+ /// @param[in] value Integer value to use for selection of them.
+ ///
+ void AddLabel(const std::string& label, int value)
+ {
+ m_interface->kodi_gui->control_spin->add_int_label(m_interface->kodiBase, m_controlHandle,
+ label.c_str(), value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To change the spin to position with them string as value.
+ ///
+ /// Format must be set to @ref ADDON_SPIN_CONTROL_TYPE_TEXT to use this function.
+ ///
+ /// @param[in] value String value to change to
+ ///
+ void SetStringValue(const std::string& value)
+ {
+ m_interface->kodi_gui->control_spin->set_string_value(m_interface->kodiBase, m_controlHandle,
+ value.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To get the current spin control position with text string value.
+ ///
+ /// Format must be set to @ref ADDON_SPIN_CONTROL_TYPE_TEXT to use this function.
+ ///
+ /// @return Currently selected string value
+ ///
+ std::string GetStringValue() const
+ {
+ std::string value;
+ char* ret = m_interface->kodi_gui->control_spin->get_string_value(m_interface->kodiBase,
+ m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ value = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return value;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To set the the range as integer of slider, e.g. -10 is the slider
+ /// start and e.g. +10 is the from here defined position where it reach the
+ /// end.
+ ///
+ /// Ad default is the range from 0 to 100.
+ ///
+ /// @param[in] start Integer start value
+ /// @param[in] end Integer end value
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used and must be defined with @ref SetType before.
+ ///
+ void SetIntRange(int start, int end)
+ {
+ m_interface->kodi_gui->control_spin->set_int_range(m_interface->kodiBase, m_controlHandle,
+ start, end);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Set the slider position with the given integer value. The Range
+ /// must be defined with a call from @ref SetIntRange before.
+ ///
+ /// @param[in] value Position in range to set with integer
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used and must be defined with @ref SetType before.
+ ///
+ void SetIntValue(int value)
+ {
+ m_interface->kodi_gui->control_spin->set_int_value(m_interface->kodiBase, m_controlHandle,
+ value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To get the current position as integer value.
+ ///
+ /// @return The position as integer
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used and must be defined with @ref SetType before.
+ ///
+ int GetIntValue() const
+ {
+ return m_interface->kodi_gui->control_spin->get_int_value(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To set the the range as float of spin, e.g. -25.0 is the spin
+ /// start and e.g. +25.0 is the from here defined position where it reach
+ /// the end.
+ ///
+ /// As default is the range 0.0 to 1.0.
+ ///
+ /// The float interval is as default 0.1 and can be changed with
+ /// @ref SetFloatInterval.
+ ///
+ /// @param[in] start Integer start value
+ /// @param[in] end Integer end value
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used and must be defined with @ref SetType before.
+ ///
+ void SetFloatRange(float start, float end)
+ {
+ m_interface->kodi_gui->control_spin->set_float_range(m_interface->kodiBase, m_controlHandle,
+ start, end);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Set the spin position with the given float value. The Range
+ /// can be defined with a call from @ref SetIntRange before, as default it
+ /// is 0.0 to 1.0.
+ ///
+ /// @param[in] value Position in range to set with float
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used and must be defined with @ref SetType before.
+ ///
+ void SetFloatValue(float value)
+ {
+ m_interface->kodi_gui->control_spin->set_float_value(m_interface->kodiBase, m_controlHandle,
+ value);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To get the current position as float value.
+ ///
+ /// @return The position as float
+ ///
+ float GetFloatValue() const
+ {
+ return m_interface->kodi_gui->control_spin->get_float_value(m_interface->kodiBase,
+ m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief To set the interval steps of spin, as default is it 0.1 If it
+ /// becomes changed with this function will a step of the user with the
+ /// value fixed here be executed.
+ ///
+ /// @param[in] interval Intervall step to set.
+ ///
+ /// @note Percent, floating point or integer are alone possible. Combining
+ /// these different values can be not together and can, therefore, only
+ /// one each can be used and must be defined with @ref SetType before.
+ ///
+ void SetFloatInterval(float interval)
+ {
+ m_interface->kodi_gui->control_spin->set_float_interval(m_interface->kodiBase, m_controlHandle,
+ interval);
+ }
+ //----------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/TextBox.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/TextBox.h
new file mode 100644
index 0000000..5ef9a15
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/TextBox.h
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/controls/text_box.h"
+#include "../Window.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace controls
+{
+
+//============================================================================
+/// @defgroup cpp_kodi_gui_windows_controls_CTextBox Control Text Box
+/// @ingroup cpp_kodi_gui_windows_controls
+/// @brief @cpp_class{ kodi::gui::controls::CTextBox }
+/// **Used to show a multi-page piece of text**\n
+/// The text box control can be used to display descriptions, help texts or
+/// other larger texts.
+///
+/// It corresponds to the representation which is also to be seen on the
+/// @ref CDialogTextViewer.
+///
+/// It has the header @ref TextBox.h "#include <kodi/gui/controls/TextBox.h>"
+/// be included to enjoy it.
+///
+/// Here you find the needed skin part for a @ref Text_Box "textbox control".
+///
+/// @note The call of the control is only possible from the corresponding
+/// window as its class and identification number is required.
+///
+class ATTR_DLL_LOCAL CTextBox : public CAddonGUIControlBase
+{
+public:
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief Construct a new control.
+ ///
+ /// @param[in] window related window control class
+ /// @param[in] controlId Used skin xml control id
+ ///
+ CTextBox(CWindow* window, int controlId) : CAddonGUIControlBase(window)
+ {
+ m_controlHandle = m_interface->kodi_gui->window->get_control_text_box(
+ m_interface->kodiBase, m_Window->GetControlHandle(), controlId);
+ if (!m_controlHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::controls::CTextBox can't create control class from Kodi !!!");
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief Destructor.
+ ///
+ ~CTextBox() override = default;
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief Set the control on window to visible.
+ ///
+ /// @param[in] visible If true visible, otherwise hidden
+ ///
+ void SetVisible(bool visible)
+ {
+ m_interface->kodi_gui->control_text_box->set_visible(m_interface->kodiBase, m_controlHandle,
+ visible);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief To reset box an remove all the text.
+ ///
+ void Reset() { m_interface->kodi_gui->control_text_box->reset(m_controlHandle, m_controlHandle); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief To set the text on box.
+ ///
+ /// @param[in] text Text to show
+ ///
+ void SetText(const std::string& text)
+ {
+ m_interface->kodi_gui->control_text_box->set_text(m_interface->kodiBase, m_controlHandle,
+ text.c_str());
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief Get the used text from control.
+ ///
+ /// @return Text shown
+ ///
+ std::string GetText() const
+ {
+ std::string text;
+ char* ret =
+ m_interface->kodi_gui->control_text_box->get_text(m_interface->kodiBase, m_controlHandle);
+ if (ret != nullptr)
+ {
+ if (std::strlen(ret))
+ text = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
+ }
+ return text;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief To scroll text on other position.
+ ///
+ /// @param[in] position The line position to scroll to
+ ///
+ void Scroll(unsigned int position)
+ {
+ m_interface->kodi_gui->control_text_box->scroll(m_interface->kodiBase, m_controlHandle,
+ position);
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief To set automatic scrolling of textbox
+ ///
+ /// Specifies the timing and conditions of any autoscrolling this textbox
+ /// should have. Times are in milliseconds. The content is delayed for the
+ /// given delay, then scrolls at a rate of one line per time interval until
+ /// the end. If the repeat tag is present, it then delays for the repeat
+ /// time, fades out over 1 second, and repeats. It does not wrap or reset
+ /// to the top at the end of the scroll.
+ ///
+ /// @param[in] delay Content delay
+ /// @param[in] time One line per time interval
+ /// @param[in] repeat Delays with given time, fades out over 1 second, and
+ /// repeats
+ ///
+ void SetAutoScrolling(int delay, int time, int repeat)
+ {
+ m_interface->kodi_gui->control_text_box->set_auto_scrolling(
+ m_interface->kodiBase, m_controlHandle, delay, time, repeat);
+ }
+ //--------------------------------------------------------------------------
+};
+
+} /* namespace controls */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/CMakeLists.txt
new file mode 100644
index 0000000..a6d32bb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ ContextMenu.h
+ ExtendedProgress.h
+ FileBrowser.h
+ Keyboard.h
+ Numeric.h
+ OK.h
+ Progress.h
+ Select.h
+ TextViewer.h
+ YesNo.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_gui_dialogs)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ContextMenu.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ContextMenu.h
new file mode 100644
index 0000000..93d75cb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ContextMenu.h
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/context_menu.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_ContextMenu Dialog Context Menu
+/// @ingroup cpp_kodi_gui_dialogs
+/// @brief @cpp_namespace{ kodi::gui::dialogs::ContextMenu }
+/// **Context menu dialog**@n
+/// The function listed below permits the call of a dialogue as context menu to
+/// select of an entry as a key
+///
+/// It has the header @ref ContextMenu.h "#include <kodi/gui/dialogs/ContextMenu.h>"
+/// be included to enjoy it.
+///
+///
+namespace ContextMenu
+{
+//==============================================================================
+/// @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 <tt>-1</tt> was nothing selected or canceled
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/ContextMenu.h>
+///
+/// const std::vector<std::string> entries
+/// {
+/// "Test 1",
+/// "Test 2",
+/// "Test 3",
+/// "Test 4",
+/// "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 ATTR_DLL_LOCAL Show(const std::string& heading, const std::vector<std::string>& entries)
+{
+ using namespace ::kodi::addon;
+ unsigned int size = static_cast<unsigned int>(entries.size());
+ const char** cEntries = static_cast<const char**>(malloc(size * sizeof(const char**)));
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ cEntries[i] = entries[i].c_str();
+ }
+ int ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(
+ CPrivateBase::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 <tt>-1</tt> was nothing selected or canceled
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/ContextMenu.h>
+///
+/// const std::vector<std::pair<std::string, std::string>> 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 ATTR_DLL_LOCAL Show(const std::string& heading,
+ const std::vector<std::pair<std::string, std::string>>& entries)
+{
+ using namespace ::kodi::addon;
+ unsigned int size = static_cast<unsigned int>(entries.size());
+ const char** cEntries = static_cast<const char**>(malloc(size * sizeof(const char**)));
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ cEntries[i] = entries[i].second.c_str();
+ }
+ int ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(
+ CPrivateBase::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 <tt>-1</tt> was nothing selected or canceled
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/ContextMenu.h>
+///
+/// const std::vector<std::pair<int, std::string>> 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 ATTR_DLL_LOCAL Show(const std::string& heading,
+ const std::vector<std::pair<int, std::string>>& entries)
+{
+ using namespace ::kodi::addon;
+ unsigned int size = static_cast<unsigned int>(entries.size());
+ const char** cEntries = static_cast<const char**>(malloc(size * sizeof(const char**)));
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ cEntries[i] = entries[i].second.c_str();
+ }
+ int ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size);
+ free(cEntries);
+ return ret;
+}
+//------------------------------------------------------------------------------
+}; // namespace ContextMenu
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h
new file mode 100644
index 0000000..3c21877
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/extended_progress.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_CExtendedProgress Dialog Extended Progress
+/// @ingroup cpp_kodi_gui_dialogs
+/// @brief @cpp_class{ kodi::gui::dialogs::ExtendedProgress }
+/// **Progress dialog shown for background work**
+///
+/// The with @ref ExtendedProgress.h "#include <kodi/gui/dialogs/ExtendedProgress.h>"
+/// given class are basically used to create Kodi's extended progress.
+///
+///
+/// --------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/ExtendedProgress.h>
+///
+/// kodi::gui::dialogs::CExtendedProgress *ext_progress = new kodi::gui::dialogs::CExtendedProgress("Test Extended progress");
+/// ext_progress->SetText("Test progress");
+/// for (unsigned int i = 0; i < 50; i += 10)
+/// {
+/// ext_progress->SetProgress(i, 100);
+/// sleep(1);
+/// }
+///
+/// ext_progress->SetTitle("Test Extended progress - Second round");
+/// ext_progress->SetText("Test progress - Step 2");
+///
+/// for (unsigned int i = 50; i < 100; i += 10)
+/// {
+/// ext_progress->SetProgress(i, 100);
+/// sleep(1);
+/// }
+/// delete ext_progress;
+/// ~~~~~~~~~~~~~
+///
+class ATTR_DLL_LOCAL CExtendedProgress
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// Construct a new dialog.
+ ///
+ /// @param[in] title [opt] Title string
+ ///
+ explicit CExtendedProgress(const std::string& title = "")
+ {
+ using namespace ::kodi::addon;
+ m_DialogHandle =
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->new_dialog(
+ CPrivateBase::m_interface->toKodi->kodiBase, title.c_str());
+ if (!m_DialogHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::CDialogExtendedProgress can't create window class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// Destructor.
+ ///
+ ~CExtendedProgress()
+ {
+ using namespace ::kodi::addon;
+ if (m_DialogHandle)
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->delete_dialog(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Get the used title.
+ ///
+ /// @return Title string
+ ///
+ std::string Title() const
+ {
+ using namespace ::kodi::addon;
+ std::string text;
+ char* strMsg = CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->get_title(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ if (strMsg != nullptr)
+ {
+ if (std::strlen(strMsg))
+ text = strMsg;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ strMsg);
+ }
+ return text;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To set the title of dialog.
+ ///
+ /// @param[in] title Title string
+ ///
+ void SetTitle(const std::string& title)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_title(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, title.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Get the used text information string.
+ ///
+ /// @return Text string
+ ///
+ std::string Text() const
+ {
+ using namespace ::kodi::addon;
+ std::string text;
+ char* strMsg = CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->get_text(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ if (strMsg != nullptr)
+ {
+ if (std::strlen(strMsg))
+ text = strMsg;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ strMsg);
+ }
+ return text;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To set the used text information string.
+ ///
+ /// @param[in] text Information text to set
+ ///
+ void SetText(const std::string& text)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_text(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, text.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To ask dialog is finished.
+ ///
+ /// @return True if on end
+ ///
+ bool IsFinished() const
+ {
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->is_finished(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Mark progress finished.
+ ///
+ void MarkFinished()
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->mark_finished(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Get the current progress position as percent.
+ ///
+ /// @return Position
+ ///
+ float Percentage() const
+ {
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->get_percentage(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To set the current progress position as percent.
+ ///
+ /// @param[in] percentage Position to use from 0.0 to 100.0
+ ///
+ void SetPercentage(float percentage)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_percentage(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, percentage);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To set progress position with predefined places.
+ ///
+ /// @param[in] currentItem Place position to use
+ /// @param[in] itemCount Amount of used places
+ ///
+ void SetProgress(int currentItem, int itemCount)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_progress(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, currentItem, itemCount);
+ }
+ //----------------------------------------------------------------------------
+
+private:
+ KODI_GUI_HANDLE m_DialogHandle;
+};
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/FileBrowser.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/FileBrowser.h
new file mode 100644
index 0000000..b7550f2
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/FileBrowser.h
@@ -0,0 +1,304 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/filebrowser.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_FileBrowser Dialog File Browser
+/// @ingroup cpp_kodi_gui_dialogs
+/// @brief @cpp_namespace{ kodi::gui::dialogs::FileBrowser }
+/// **File browser dialog**\n
+/// The functions listed below of the class "FileBrowser" offer the possibility
+/// to select to a file by the user of the add-on.
+///
+/// It allows all the options that are possible in Kodi itself and offers all
+/// support file types.
+///
+/// It has the header @ref FileBrowser.h "#include <kodi/gui/dialogs/FileBrowser.h>"
+/// be included to enjoy it.
+///
+namespace FileBrowser
+{
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_FileBrowser
+/// @brief Directory selection dialog.
+///
+/// @param[in] shares With Shares becomes the available start folders be set
+/// @param[in] heading Dialog header name
+/// @param[in,out] path As in the path to start and return value about
+/// selected directory
+/// @param[in] writeOnly [opt] If set only writeable folders are shown
+/// @return False if selection becomes canceled
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/FileBrowser.h>
+///
+/// // Example show directory selection dialog with on 'share' (first value)
+/// // defined directory types.
+/// //
+/// // If this becomes leaved empty and 'directory' is empty goes it to the
+/// // base path of the hard disk.
+/// //
+/// // Also can be with path written to 'directory' before the dialog forced
+/// // to a start place.
+/// std::string directory;
+/// bool ret = kodi::gui::dialogs::FileBrowser::ShowAndGetDirectory("local|network|removable",
+/// "Test directory selection",
+/// directory,
+/// false);
+/// fprintf(stderr, "Selected directory is : %s and was %s\n", directory.c_str(), ret ? "OK" : "Canceled");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetDirectory(const std::string& shares,
+ const std::string& heading,
+ std::string& path,
+ bool writeOnly = false)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_directory(
+ CPrivateBase::m_interface->toKodi->kodiBase, shares.c_str(), heading.c_str(), path.c_str(),
+ &retString, writeOnly);
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ path = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_FileBrowser
+/// @brief File selection dialog.
+///
+/// @param[in] shares With Shares becomes the available start folders be set.
+/// @param[in] mask The mask to filter visible files, e.g. ".m3u|.pls|.b4s|.wpl"
+/// @param[in] heading Dialog header name
+/// @param[in,out] path As in the path to start and Return value about selected
+/// file
+/// @param[in] useThumbs [opt] If set show thumbs if possible on dialog
+/// @param[in] useFileDirectories [opt] If set also packages (e.g. *.zip) are
+/// handled as directories.
+/// @return False if selection becomes canceled
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetFile(const std::string& shares,
+ const std::string& mask,
+ const std::string& heading,
+ std::string& path,
+ bool useThumbs = false,
+ bool useFileDirectories = false)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file(
+ CPrivateBase::m_interface->toKodi->kodiBase, shares.c_str(), mask.c_str(), heading.c_str(),
+ path.c_str(), &retString, useThumbs, useFileDirectories);
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ path = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_FileBrowser
+/// @brief File selection from a directory.
+///
+/// @param[in] directory The directory name where the dialog start, possible are
+/// normal names and kodi's special names
+/// @param[in] mask The mask to filter visible files, e.g. ".m3u|.pls|.b4s|.wpl"
+/// @param[in] heading Dialog header name
+/// @param[in,out] path As in the path to start and Return value about selected
+/// file
+/// @param[in] useThumbs [opt] If set show thumbs if possible on dialog
+/// @param[in] useFileDirectories [opt] If set also packages (e.g. *.zip) are
+/// handled as directories
+/// @param[in] singleList [opt]
+/// @return False if selection becomes canceled
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetFileFromDir(const std::string& directory,
+ const std::string& mask,
+ const std::string& heading,
+ std::string& path,
+ bool useThumbs = false,
+ bool useFileDirectories = false,
+ bool singleList = false)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret =
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_from_dir(
+ CPrivateBase::m_interface->toKodi->kodiBase, directory.c_str(), mask.c_str(),
+ heading.c_str(), path.c_str(), &retString, useThumbs, useFileDirectories, singleList);
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ path = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_FileBrowser
+/// @brief File selection dialog to get several in to a list.
+///
+/// @param[in] shares With Shares becomes the available start folders be set.
+/// @param[in] mask The mask to filter visible files, e.g. ".m3u|.pls|.b4s|.wpl"
+/// @param[in] heading Dialog header name
+/// @param[out] fileList Return value about selected files
+/// @param[in] useThumbs [opt] If set show thumbs if possible on dialog.
+/// @param[in] useFileDirectories [opt] If set also packages (e.g. *.zip) are
+/// handled as directories.
+/// @return False if selection becomes canceled.
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetFileList(const std::string& shares,
+ const std::string& mask,
+ const std::string& heading,
+ std::vector<std::string>& fileList,
+ bool useThumbs = false,
+ bool useFileDirectories = false)
+{
+ using namespace ::kodi::addon;
+ char** list = nullptr;
+ unsigned int listSize = 0;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_list(
+ CPrivateBase::m_interface->toKodi->kodiBase, shares.c_str(), mask.c_str(), heading.c_str(),
+ &list, &listSize, useThumbs, useFileDirectories);
+ if (ret)
+ {
+ for (unsigned int i = 0; i < listSize; ++i)
+ fileList.emplace_back(list[i]);
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->clear_file_list(
+ CPrivateBase::m_interface->toKodi->kodiBase, &list, listSize);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_FileBrowser
+/// @brief Source selection dialog.
+///
+/// @param[in,out] path As in the path to start and Return value about selected
+/// source
+/// @param[in] allowNetworkShares Allow also access to network
+/// @param[in] additionalShare [opt] With additionalShare becomes the available
+/// start folders be set.
+/// @param[in] type [opt]
+/// @return False if selection becomes canceled
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetSource(std::string& path,
+ bool allowNetworkShares,
+ const std::string& additionalShare = "",
+ const std::string& type = "")
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_source(
+ CPrivateBase::m_interface->toKodi->kodiBase, path.c_str(), &retString, allowNetworkShares,
+ additionalShare.c_str(), type.c_str());
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ path = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_FileBrowser
+/// @brief Image selection dialog.
+///
+/// @param[in] shares With Shares becomes the available start folders be set
+/// @param[in] heading Dialog header name
+/// @param[out] path Return value about selected image
+/// @return False if selection becomes canceled
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetImage(const std::string& shares,
+ const std::string& heading,
+ std::string& path)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image(
+ CPrivateBase::m_interface->toKodi->kodiBase, shares.c_str(), heading.c_str(), path.c_str(),
+ &retString);
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ path = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_FileBrowser
+/// @brief Image selection dialog to get several in to a list.
+///
+/// @param[in] shares With Shares becomes the available start folders be set
+/// @param[in] heading Dialog header name
+/// @param[out] file_list Return value about selected images
+/// @return False if selection becomes canceled
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetImageList(const std::string& shares,
+ const std::string& heading,
+ std::vector<std::string>& file_list)
+{
+ using namespace ::kodi::addon;
+ char** list = nullptr;
+ unsigned int listSize = 0;
+ bool ret =
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image_list(
+ CPrivateBase::m_interface->toKodi->kodiBase, shares.c_str(), heading.c_str(), &list,
+ &listSize);
+ if (ret)
+ {
+ for (unsigned int i = 0; i < listSize; ++i)
+ file_list.emplace_back(list[i]);
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->clear_file_list(
+ CPrivateBase::m_interface->toKodi->kodiBase, &list, listSize);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+}; // namespace FileBrowser
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Keyboard.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Keyboard.h
new file mode 100644
index 0000000..9aded50
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Keyboard.h
@@ -0,0 +1,405 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/keyboard.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//================================================================================
+/// @defgroup cpp_kodi_gui_dialogs_Keyboard Dialog Keyboard
+/// @ingroup cpp_kodi_gui_dialogs
+/// @brief @cpp_namespace{ kodi::gui::dialogs::Keyboard }
+/// **Keyboard dialogs**\n
+/// The functions listed below have to be permitted by the user for the
+/// representation of a keyboard around an input.
+///
+/// The class supports several kinds, from an easy text choice up to the
+/// passport Word production and their confirmation for add-on.
+///
+/// It has the header @ref Keyboard.h "#include <kodi/gui/dialogs/Keyboard.h>"
+/// be included to enjoy it.
+///
+namespace Keyboard
+{
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Show keyboard with initial value `text` and replace with result
+/// string.
+///
+/// @param[in,out] text Overwritten with user input if return=true.
+/// @param[in] heading String shown on dialog title.
+/// @param[in] allowEmptyResult Whether a blank password is valid or not.
+/// @param[in] hiddenInput [opt] The inserted input is not shown as text.
+/// @param[in] autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog
+/// open indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/Keyboard.h>
+///
+/// // The example shows the display of keyboard call dialog at Kodi from the add-on.
+/// // Below all values are set, however, can last two (hidden input = false and autoCloseMs = 0)
+/// // to be released if not needed.
+/// std::string text = "Please change me to them want you want"; // It can be leaved empty or a entry text added
+/// bool bRet = ::kodi::gui::dialogs::Keyboard::ShowAndGetInput(text,
+/// "Demonstration text entry",
+/// true,
+/// false,
+/// 0);
+/// fprintf(stderr, "Written keyboard input is : '%s' and was %s\n",
+/// text.c_str(), bRet ? "OK" : "Canceled");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetInput(std::string& text,
+ const std::string& heading,
+ bool allowEmptyResult,
+ bool hiddenInput = false,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret =
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input_with_head(
+ CPrivateBase::m_interface->toKodi->kodiBase, text.c_str(), &retString, heading.c_str(),
+ allowEmptyResult, hiddenInput, autoCloseMs);
+ if (retString != nullptr)
+ {
+ text = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief The example shows the display of keyboard call dialog at Kodi
+/// from the add-on.
+///
+/// @param[out] text Overwritten with user input if return=true.
+/// @param[in] allowEmptyResult If set to true keyboard can also exited without
+/// entered text.
+/// @param[in] autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog
+/// open indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetInput(std::string& text,
+ bool allowEmptyResult,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input(
+ CPrivateBase::m_interface->toKodi->kodiBase, text.c_str(), &retString, allowEmptyResult,
+ autoCloseMs);
+ if (retString != nullptr)
+ {
+ text = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Shows keyboard and prompts for a password. Differs from
+/// `ShowAndVerifyNewPassword()` in that no second verification.
+///
+/// @param[in,out] newPassword Overwritten with user input if return=true.
+/// @param[in] heading String shown on dialog title.
+/// @param[in] allowEmptyResult Whether a blank password is valid or not.
+/// @param[in] autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog
+/// open indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetNewPassword(std::string& newPassword,
+ const std::string& heading,
+ bool allowEmptyResult,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard
+ ->show_and_get_new_password_with_head(
+ CPrivateBase::m_interface->toKodi->kodiBase, newPassword.c_str(), &retString,
+ heading.c_str(), allowEmptyResult, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Shows keyboard and prompts for a password. Differs from
+/// `ShowAndVerifyNewPassword()` in that no second verification.
+///
+/// @param[in,out] newPassword Overwritten with user input if return=true.
+/// @param[in] autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog
+/// open indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetNewPassword(std::string& newPassword,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password(
+ CPrivateBase::m_interface->toKodi->kodiBase, newPassword.c_str(), &retString, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Show keyboard twice to get and confirm a user-entered password
+/// string.
+///
+/// @param[out] newPassword Overwritten with user input if return=true.
+/// @param[in] heading String shown on dialog title.
+/// @param[in] allowEmptyResult
+/// @param[in] autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog
+/// open indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/General.h>
+/// #include <kodi/gui/dialogs/Keyboard.h>
+///
+/// // The example below shows the complete use of keyboard dialog for password
+/// // check. If only one check from add-on needed can be function with retries
+/// // set to '0' called alone.
+/// //
+/// // The use of MD5 translated password is always required for the check on Kodi!
+///
+/// int maxretries = 3;
+/// // Password names need to be send as md5 sum to kodi.
+/// std::string password;
+/// kodi::GetMD5("kodi", password);
+///
+/// // To the loop about password checks.
+/// int ret;
+/// for (unsigned int i = 0; i < maxretries; i++)
+/// {
+/// // Ask the user about the password.
+/// ret = ::kodi::gui::dialogs::Keyboard::ShowAndVerifyPassword(password, "Demo password call for PW 'kodi'", i, 0);
+/// if (ret == 0)
+/// {
+/// fprintf(stderr, "Password successfully confirmed after '%i' tries\n", i+1);
+/// break;
+/// }
+/// else if (ret < 0)
+/// {
+/// fprintf(stderr, "Canceled editing on try '%i'\n", i+1);
+/// break;
+/// }
+/// else // if (ret > 0)
+/// {
+/// fprintf(stderr, "Wrong password entered on try '%i'\n", i+1);
+/// }
+/// }
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndVerifyNewPassword(std::string& newPassword,
+ const std::string& heading,
+ bool allowEmptyResult,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard
+ ->show_and_verify_new_password_with_head(
+ CPrivateBase::m_interface->toKodi->kodiBase, &retString, heading.c_str(),
+ allowEmptyResult, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Show keyboard twice to get and confirm a user-entered password
+/// string.
+///
+/// @param[out] newPassword Overwritten with user input if return=true.
+/// @param[in] autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog
+/// open indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndVerifyNewPassword(std::string& newPassword,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret =
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password(
+ CPrivateBase::m_interface->toKodi->kodiBase, &retString, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Show keyboard and verify user input against `password`.
+///
+/// @param[in,out] password Value to compare against user input.
+/// @param[in] heading String shown on dialog title.
+/// @param[in] retries If greater than 0, shows "Incorrect password, %d retries
+/// left" on dialog line 2, else line 2 is blank.
+/// @param[in] autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog
+/// open indefinitely.
+/// @return 0 if successful display and user input. 1 if unsuccessful input.
+/// -1 if no user input or canceled editing.
+///
+inline int ATTR_DLL_LOCAL ShowAndVerifyPassword(std::string& password,
+ const std::string& heading,
+ int retries,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ int ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_password(
+ CPrivateBase::m_interface->toKodi->kodiBase, password.c_str(), &retString, heading.c_str(),
+ retries, autoCloseMs);
+ if (retString != nullptr)
+ {
+ password = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Shows a filter related keyboard.
+///
+/// @param[in,out] text Overwritten with user input if return=true.
+/// @param[in] searching Use dialog for search and send our search message in
+/// safe way (only the active window needs it)
+/// - header name if true is "Enter search string"
+/// - header name if false is "Enter value"
+/// @param autoCloseMs [opt] To close the dialog after a specified time, in
+/// milliseconds, default is 0 which keeps the dialog open
+/// indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetFilter(std::string& text,
+ bool searching,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_filter(
+ CPrivateBase::m_interface->toKodi->kodiBase, text.c_str(), &retString, searching,
+ autoCloseMs);
+ if (retString != nullptr)
+ {
+ text = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Send a text to a visible keyboard.
+///
+/// @param[in] text Overwritten with user input if return=true.
+/// @param[in] closeKeyboard [opt] The open dialog is if also closed on 'true'.
+/// @return true if successful done, false if unsuccessful or keyboard not
+/// present.
+///
+inline bool ATTR_DLL_LOCAL SendTextToActiveKeyboard(const std::string& text,
+ bool closeKeyboard = false)
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->send_text_to_active_keyboard(
+ CPrivateBase::m_interface->toKodi->kodiBase, text.c_str(), closeKeyboard);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Check for visible keyboard on GUI.
+///
+/// @return true if keyboard present, false if not present
+///
+inline bool ATTR_DLL_LOCAL IsKeyboardActivated()
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogKeyboard->is_keyboard_activated(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
+}; // namespace Keyboard
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Numeric.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Numeric.h
new file mode 100644
index 0000000..54b7720
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Numeric.h
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/numeric.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_Numeric Dialog Numeric
+/// @ingroup cpp_kodi_gui_dialogs
+/// @{
+/// @brief @cpp_namespace{ kodi::gui::dialogs::Numeric }
+/// **Numeric dialogs**\n
+/// The functions listed below have to be permitted by the user for the
+/// representation of a numeric keyboard around an input.
+///
+/// The class supports several kinds, from an easy number choice up to the
+/// passport Word production and their confirmation for add-on.
+///
+/// It has the header @ref Numeric.h "#include <kodi/gui/dialogs/Numeric.h>"
+/// be included to enjoy it.
+///
+namespace Numeric
+{
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Use dialog to get numeric new password
+///
+/// @param[out] newPassword String to preload into the keyboard accumulator.
+/// Overwritten with user input if return=true.
+/// Returned in MD5 format.
+/// @return true if successful display and user input entry/re-entry. false if
+/// unsuccessful display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndVerifyNewPassword(std::string& newPassword)
+{
+ using namespace ::kodi::addon;
+ char* pw = nullptr;
+ bool ret =
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_new_password(
+ CPrivateBase::m_interface->toKodi->kodiBase, &pw);
+ if (pw != nullptr)
+ {
+ newPassword = pw;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase, pw);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+///
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Use dialog to verify numeric password.
+///
+/// @param[in] password Password to compare with user input, need
+/// in MD5 format.
+/// @param[in] heading Heading to display
+/// @param[in] retries If greater than 0, shows "Incorrect
+/// password, %d retries left" on dialog
+/// line 2, else line 2 is blank.
+/// @return Possible values:
+/// - 0 if successful display and user input.
+/// - 1 if unsuccessful input.
+/// - -1 if no user input or canceled editing.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <stdio.h> // fprintf
+/// #include <kodi/General.h>
+/// #include <kodi/gui/dialogs/Numeric.h>
+///
+/// // The example below shows the complete use of keyboard dialog for password
+/// // check. If only one check from add-on needed can be function with retries
+/// // set to '0' called alone.
+/// //
+/// // The use of MD5 translated password is always required for the check on Kodi!
+///
+/// int maxretries = 3;
+///
+/// // Password names need to be send as md5 sum to kodi.
+/// std::string password = kodi::GetMD5("1234");
+///
+/// // To the loop about password checks.
+/// int ret;
+/// for (unsigned int i = 0; i < maxretries; i++)
+/// {
+/// // Ask the user about the password.
+/// ret = kodi::gui::dialogs::Numeric::ShowAndVerifyPassword(password, "Demo numeric password call for PW '1234'", i);
+/// if (ret == 0)
+/// {
+/// fprintf(stderr, "Numeric password successfully confirmed after '%i' tries\n", i+1);
+/// break;
+/// }
+/// else if (ret < 0)
+/// {
+/// fprintf(stderr, "Canceled editing on try '%i'\n", i+1);
+/// break;
+/// }
+/// else // if (ret > 0)
+/// {
+/// fprintf(stderr, "Wrong numeric password entered on try '%i'\n", i+1);
+/// }
+/// }
+/// ~~~~~~~~~~~~~
+///
+inline int ATTR_DLL_LOCAL ShowAndVerifyPassword(const std::string& password,
+ const std::string& heading,
+ int retries)
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_password(
+ CPrivateBase::m_interface->toKodi->kodiBase, password.c_str(), heading.c_str(), retries);
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Use dialog to verify numeric password
+///
+/// @param[in,out] toVerify Value to compare against user input.
+/// @param[in] heading Heading to display
+/// @param[in] verifyInput If set as true we verify the users input versus
+/// toVerify.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndVerifyInput(std::string& toVerify,
+ const std::string& heading,
+ bool verifyInput)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_input(
+ CPrivateBase::m_interface->toKodi->kodiBase, toVerify.c_str(), &retString, heading.c_str(),
+ verifyInput);
+ if (retString != nullptr)
+ {
+ toVerify = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Use dialog to get time value.
+///
+/// @param[out] time Overwritten with user input if return=true and time
+/// inserted.
+/// @param[in] heading Heading to display.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <stdio.h> // printf
+/// #include <time.h> // time_t, struct tm, time, localtime, strftime
+/// #include <kodi/gui/dialogs/Numeric.h>
+///
+/// time_t rawtime;
+/// struct tm * timeinfo;
+/// char buffer [10];
+///
+/// time (&rawtime);
+/// timeinfo = localtime(&rawtime);
+/// bool bRet = kodi::gui::dialogs::Numeric::ShowAndGetTime(*timeinfo, "Selected time test call");
+/// strftime(buffer, sizeof(buffer), "%H:%M.", timeinfo);
+/// printf("Selected time it's %s and was on Dialog %s\n", buffer, bRet ? "OK" : "Canceled");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetTime(tm& time, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_time(
+ CPrivateBase::m_interface->toKodi->kodiBase, &time, heading.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Use dialog to get date value.
+///
+/// @param[in,out] date Overwritten with user input if return=true and date
+/// inserted.
+/// @param[in] heading Heading to display
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <stdio.h> // printf
+/// #include <time.h> // time_t, struct tm, time, localtime, strftime
+/// #include <kodi/gui/dialogs/Numeric.h>
+///
+/// time_t rawtime;
+/// struct tm * timeinfo;
+/// char buffer [20];
+///
+/// time (&rawtime);
+/// timeinfo = localtime(&rawtime);
+/// bool bRet = kodi::gui::dialogs::Numeric::ShowAndGetDate(*timeinfo, "Selected date test call");
+/// strftime(buffer, sizeof(buffer), "%Y-%m-%d", timeinfo);
+/// printf("Selected date it's %s and was on Dialog %s\n", buffer, bRet ? "OK" : "Canceled");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetDate(tm& date, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_date(
+ CPrivateBase::m_interface->toKodi->kodiBase, &date, heading.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Use dialog to get a IP
+///
+/// @param[in,out] ipAddress Overwritten with user input if return=true and
+/// IP address inserted.
+/// @param[in] heading Heading to display.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetIPAddress(std::string& ipAddress, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_ip_address(
+ CPrivateBase::m_interface->toKodi->kodiBase, ipAddress.c_str(), &retString, heading.c_str());
+ if (retString != nullptr)
+ {
+ ipAddress = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Use dialog to get normal number.
+///
+/// @param[in,out] input Overwritten with user input if return=true and time
+/// in seconds inserted
+/// @param[in] heading Heading to display
+/// @param[in] autoCloseTimeoutMs [opt] To close the dialog after a specified
+/// time, in milliseconds, default is 0
+/// which keeps the dialog open
+/// indefinitely.
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <stdio.h> // printf
+/// #include <stdlib.h> // strtoull (C++11)
+/// #include <kodi/gui/dialogs/Numeric.h>
+///
+/// std::string number;
+/// bool bRet = kodi::gui::dialogs::Numeric::ShowAndGetNumber(number, "Number test call");
+/// printf("Written number input is : %llu and was %s\n",
+/// strtoull(number.c_str(), nullptr, 0), bRet ? "OK" : "Canceled");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetNumber(std::string& input,
+ const std::string& heading,
+ unsigned int autoCloseTimeoutMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_number(
+ CPrivateBase::m_interface->toKodi->kodiBase, input.c_str(), &retString, heading.c_str(),
+ autoCloseTimeoutMs);
+ if (retString != nullptr)
+ {
+ input = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Numeric
+/// @brief Show numeric keypad to get seconds.
+///
+/// @param[in,out] time Overwritten with user input if return=true and time
+/// in seconds inserted.
+/// @param[in] heading Heading to display
+/// @return true if successful display and user input. false if unsuccessful
+/// display, no user input, or canceled editing.
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetSeconds(std::string& time, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_seconds(
+ CPrivateBase::m_interface->toKodi->kodiBase, time.c_str(), &retString, heading.c_str());
+ if (retString != nullptr)
+ {
+ time = retString;
+ CPrivateBase::m_interface->toKodi->free_string(CPrivateBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ return ret;
+}
+//------------------------------------------------------------------------------
+}; // namespace Numeric
+/// @}
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/OK.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/OK.h
new file mode 100644
index 0000000..a9fcb3f
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/OK.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/ok.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_OK Dialog OK
+/// @ingroup cpp_kodi_gui_dialogs
+/// @{
+/// @brief @cpp_namespace{ kodi::gui::dialogs::OK }
+/// **OK dialog**\n
+/// The functions listed below permit the call of a dialogue of information, a
+/// confirmation of the user by press from OK required.
+///
+/// It has the header @ref OK.h "#include <kodi/gui/dialogs/OK.h>"
+/// be included to enjoy it.
+///
+namespace OK
+{
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_OK
+/// @brief Use dialog to inform user with text and confirmation with OK with
+/// continued string.
+///
+/// @param[in] heading Dialog heading.
+/// @param[in] text Multi-line text.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/OK.h>
+/// ...
+/// kodi::gui::dialogs::OK::ShowAndGetInput("Test dialog", "Hello World!\nI'm a call from add-on\n :) :D");
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL ShowAndGetInput(const std::string& heading, const std::string& text)
+{
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_single_text(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), text.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_OK
+/// @brief Use dialog to inform user with text and confirmation with OK with
+/// strings separated to the lines.
+///
+/// @param[in] heading Dialog heading.
+/// @param[in] line0 Line #1 text.
+/// @param[in] line1 Line #2 text.
+/// @param[in] line2 Line #3 text.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/OK.h>
+/// ...
+/// kodi::gui::dialogs::OK::ShowAndGetInput("Test dialog", "Hello World!", "I'm a call from add-on", " :) :D");
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL ShowAndGetInput(const std::string& heading,
+ const std::string& line0,
+ const std::string& line1,
+ const std::string& line2)
+{
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_line_text(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), line0.c_str(), line1.c_str(),
+ line2.c_str());
+}
+//------------------------------------------------------------------------------
+} // namespace OK
+/// @}
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Progress.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Progress.h
new file mode 100644
index 0000000..3dfd8ba
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Progress.h
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/progress.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_CProgress Dialog Progress
+/// @ingroup cpp_kodi_gui_dialogs
+/// @brief @cpp_class{ kodi::gui::dialogs::CProgress }
+/// **Progress dialog shown in center**\n
+/// The with @ref Progress.h "#include <kodi/gui/dialogs/Progress.h>"
+/// given class are basically used to create Kodi's progress dialog with named
+/// text fields.
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/Progress.h>
+///
+/// kodi::gui::dialogs::CProgress *progress = new kodi::gui::dialogs::CProgress;
+/// progress->SetHeading("Test progress");
+/// progress->SetLine(1, "line 1");
+/// progress->SetLine(2, "line 2");
+/// progress->SetLine(3, "line 3");
+/// progress->SetCanCancel(true);
+/// progress->ShowProgressBar(true);
+/// progress->Open();
+/// for (unsigned int i = 0; i < 100; i += 10)
+/// {
+/// progress->SetPercentage(i);
+/// sleep(1);
+/// }
+/// delete progress;
+/// ~~~~~~~~~~~~~
+///
+class ATTR_DLL_LOCAL CProgress
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief Construct a new dialog
+ ///
+ CProgress()
+ {
+ using namespace ::kodi::addon;
+ m_DialogHandle = CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->new_dialog(
+ CPrivateBase::m_interface->toKodi->kodiBase);
+ if (!m_DialogHandle)
+ kodi::Log(ADDON_LOG_FATAL,
+ "kodi::gui::dialogs::CProgress can't create window class from Kodi !!!");
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief Destructor
+ ///
+ ~CProgress()
+ {
+ using namespace ::kodi::addon;
+ if (m_DialogHandle)
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->delete_dialog(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To open the dialog
+ ///
+ void Open()
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->open(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief Set the heading title of dialog
+ ///
+ /// @param[in] heading Title string to use
+ ///
+ void SetHeading(const std::string& heading)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->set_heading(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, heading.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To set the line text field on dialog from 0 - 2
+ ///
+ /// @param[in] iLine Line number
+ /// @param[in] line Text string
+ ///
+ void SetLine(unsigned int iLine, const std::string& line)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->set_line(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, iLine, line.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To enable and show cancel button on dialog
+ ///
+ /// @param[in] canCancel if true becomes it shown
+ ///
+ void SetCanCancel(bool canCancel)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->set_can_cancel(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, canCancel);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To check dialog for clicked cancel button
+ ///
+ /// @return True if canceled
+ ///
+ bool IsCanceled() const
+ {
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->is_canceled(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief Get the current progress position as percent
+ ///
+ /// @param[in] percentage Position to use from 0 to 100
+ ///
+ void SetPercentage(int percentage)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->set_percentage(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, percentage);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To set the current progress position as percent
+ ///
+ /// @return Current Position used from 0 to 100
+ ///
+ int GetPercentage() const
+ {
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->get_percentage(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To show or hide progress bar dialog
+ ///
+ /// @param[in] onOff If true becomes it shown
+ ///
+ void ShowProgressBar(bool onOff)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->show_progress_bar(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, onOff);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief Set the maximum position of progress, needed if `SetProgressAdvance(...)` is used
+ ///
+ /// @param[in] max Biggest usable position to use
+ ///
+ void SetProgressMax(int max)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->set_progress_max(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, max);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To increase progress bar by defined step size until reach of maximum position
+ ///
+ /// @param[in] steps Step size to increase, default is 1
+ ///
+ void SetProgressAdvance(int steps = 1)
+ {
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->set_progress_advance(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle, steps);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
+ /// @brief To check progress was canceled on work
+ ///
+ /// @return True if aborted
+ ///
+ bool Abort()
+ {
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogProgress->abort(
+ CPrivateBase::m_interface->toKodi->kodiBase, m_DialogHandle);
+ }
+ //----------------------------------------------------------------------------
+
+private:
+ KODI_GUI_HANDLE m_DialogHandle;
+};
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Select.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Select.h
new file mode 100644
index 0000000..09bccc3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Select.h
@@ -0,0 +1,270 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/select.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_Select_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_gui_dialogs_Select
+/// @brief **Dialog Select definition values**\n
+/// Data structures associated with this dialog.
+///
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Select_Defs
+/// @brief **Selection entry structure**\n
+/// Used to provide the necessary data for the selection dialog and to declare
+/// the selected position in it.
+///
+typedef struct SSelectionEntry
+{
+ /*! \cond PRIVATE */
+ SSelectionEntry() = default;
+ /*! \endcond */
+
+ /// 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 = false;
+} SSelectionEntry;
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_Select Dialog Select
+/// @ingroup cpp_kodi_gui_dialogs
+/// @{
+/// @brief @cpp_namespace{ kodi::gui::dialogs::Select }
+/// **Selection dialog**\n
+/// The function listed below permits the call of a dialogue to select of an
+/// entry as a key
+///
+/// It has the header @ref Select.h "#include <kodi/gui/dialogs/Select.h>"
+/// be included to enjoy it.
+///
+///
+namespace Select
+{
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Select
+/// @brief Show a selection dialog about given parts.
+///
+/// @param[in] heading Dialog heading name
+/// @param[in] entries String list about entries
+/// @param[in] selected [opt] Predefined selection (default is <tt>-1</tt> 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 <tt>-1</tt> was nothing selected or
+/// canceled
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/Select.h>
+///
+/// const std::vector<std::string> entries
+/// {
+/// "Test 1",
+/// "Test 2",
+/// "Test 3",
+/// "Test 4",
+/// "Test 5"
+/// };
+///
+/// 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 ATTR_DLL_LOCAL Show(const std::string& heading,
+ const std::vector<std::string>& entries,
+ int selected = -1,
+ unsigned int autoclose = 0)
+{
+ using namespace ::kodi::addon;
+ unsigned int size = static_cast<unsigned int>(entries.size());
+ const char** cEntries = (const char**)malloc(size * sizeof(const char**));
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ cEntries[i] = entries[i].c_str();
+ }
+ int ret = CPrivateBase::m_interface->toKodi->kodi_gui->dialogSelect->open(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size, selected,
+ autoclose);
+ free(cEntries);
+ 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 @ref SSelectionEntry, where a ID string can be defined.
+///
+/// @param[in] heading Dialog heading name
+/// @param[in] entries @ref SSelectionEntry list about entries
+/// @param[in] selected [opt] Predefined selection (default is <tt>-1</tt> 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 <tt>-1</tt> was nothing selected
+/// or canceled
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/Select.h>
+///
+/// std::vector<kodi::gui::dialogs::SSelectionEntry> 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 ATTR_DLL_LOCAL Show(const std::string& heading,
+ std::vector<kodi::gui::dialogs::SSelectionEntry>& entries,
+ int selected = -1,
+ unsigned int autoclose = 0)
+{
+ using namespace ::kodi::addon;
+ unsigned int size = static_cast<unsigned int>(entries.size());
+ const char** cEntries = static_cast<const char**>(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 = CPrivateBase::m_interface->toKodi->kodi_gui->dialogSelect->open(
+ CPrivateBase::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 @ref 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 <tt>empty</tt> was nothing selected
+/// or canceled
+///
+/// With selected on @ref SSelectionEntry can be a pre selection defined.
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/Select.h>
+///
+/// std::vector<kodi::gui::dialogs::SSelectionEntry> 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 ATTR_DLL_LOCAL
+ShowMultiSelect(const std::string& heading,
+ std::vector<kodi::gui::dialogs::SSelectionEntry>& entries,
+ int autoclose = 0)
+{
+ using namespace ::kodi::addon;
+ unsigned int size = static_cast<unsigned int>(entries.size());
+ const char** cEntryIDs = static_cast<const char**>(malloc(size * sizeof(const char*)));
+ const char** cEntryNames = static_cast<const char**>(malloc(size * sizeof(const char*)));
+ bool* cEntriesSelected = static_cast<bool*>(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 = CPrivateBase::m_interface->toKodi->kodi_gui->dialogSelect->open_multi_select(
+ CPrivateBase::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;
+}
+//------------------------------------------------------------------------------
+}; // namespace Select
+/// @}
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/TextViewer.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/TextViewer.h
new file mode 100644
index 0000000..7c2e6ca
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/TextViewer.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015-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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/text_viewer.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_TextViewer Dialog Text Viewer
+/// @ingroup cpp_kodi_gui_dialogs
+/// @{
+/// @brief @cpp_namespace{ kodi::gui::dialogs::TextViewer }
+/// **Text viewer dialog**\n
+/// The text viewer dialog can be used to display descriptions, help texts or
+/// other larger texts.
+///
+/// In order to achieve a line break is a <b>\\n</b> directly in the text or
+/// in the <em>"./resources/language/resource.language.??_??/strings.po"</em>
+/// to call with <b>std::string kodi::general::GetLocalizedString(...);</b>.
+///
+/// It has the header @ref TextViewer.h "#include <kodi/gui/dialogs/TextViewer.h>"
+/// be included to enjoy it.
+///
+namespace TextViewer
+{
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_TextViewer
+/// @brief Show info text dialog
+///
+/// @param[in] heading mall heading text
+/// @param[in] text Showed text on dialog
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/TextViewer.h>
+///
+/// kodi::gui::dialogs::TextViewer::Show("The Wizard of Oz (1939 film)",
+/// "The Wizard of Oz is a 1939 American musical comedy-drama fantasy film "
+/// "produced by Metro-Goldwyn-Mayer, and the most well-known and commercially "
+/// "successful adaptation based on the 1900 novel The Wonderful Wizard of Oz "
+/// "by L. Frank Baum. The film stars Judy Garland as Dorothy Gale. The film"
+/// "co-stars Terry the dog, billed as Toto; Ray Bolger, Jack Haley, Bert Lahr, "
+/// "Frank Morgan, Billie Burke, Margaret Hamilton, with Charley Grapewin and "
+/// "Clara Blandick, and the Singer Midgets as the Munchkins.\n"
+/// "\n"
+/// "Notable for its use of Technicolor, fantasy storytelling, musical score and "
+/// "unusual characters, over the years it has become an icon of American popular "
+/// "culture. It was nominated for six Academy Awards, including Best Picture but "
+/// "lost to Gone with the Wind. It did win in two other categories including Best "
+/// "Original Song for \"Over the Rainbow\". However, the film was a box office "
+/// "disappointment on its initial release, earning only $3,017,000 on a $2,777,000 "
+/// "budget, despite receiving largely positive reviews. It was MGM's most "
+/// "expensive production at that time, and did not completely recoup the studio's "
+/// "investment and turn a profit until theatrical re-releases starting in 1949.\n"
+/// "\n"
+/// "The 1956 broadcast television premiere of the film on CBS re-introduced the "
+/// "film to the wider public and eventually made the presentation an annual "
+/// "tradition, making it one of the most known films in cinema history. The "
+/// "film was named the most-viewed motion picture on television syndication by "
+/// "the Library of Congress who also included the film in its National Film "
+/// "Registry in its inaugural year in 1989. Designation on the registry calls "
+/// "for efforts to preserve it for being \"culturally, historically, and "
+/// "aesthetically significant\". It is also one of the few films on UNESCO's "
+/// "Memory of the World Register.\n"
+/// "\n"
+/// "The Wizard of Oz is often ranked on best-movie lists in critics' and public "
+/// "polls. It is the source of many quotes referenced in modern popular culture. "
+/// "It was directed primarily by Victor Fleming (who left production to take "
+/// "over direction on the troubled Gone with the Wind production). Noel Langley, "
+/// "Florence Ryerson and Edgar Allan Woolf received credit for the screenplay, "
+/// "but there were uncredited contributions by others. The songs were written "
+/// "by Edgar \"Yip\" Harburg (lyrics) and Harold Arlen (music). The incidental "
+/// "music, based largely on the songs, was composed by Herbert Stothart, with "
+/// "interspersed renderings from classical composers.\n");
+/// ~~~~~~~~~~~~~
+///
+inline void ATTR_DLL_LOCAL Show(const std::string& heading, const std::string& text)
+{
+ using namespace ::kodi::addon;
+ CPrivateBase::m_interface->toKodi->kodi_gui->dialogTextViewer->open(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), text.c_str());
+}
+//------------------------------------------------------------------------------
+}; // namespace TextViewer
+/// @}
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/YesNo.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/YesNo.h
new file mode 100644
index 0000000..e4d3d12
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/YesNo.h
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/yes_no.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_dialogs_YesNo Dialog Yes/No
+/// @ingroup cpp_kodi_gui_dialogs
+/// @{
+/// @brief @cpp_namespace{ kodi::gui::dialogs::YesNo }
+/// **Yes / No dialog**\n
+/// The Yes / No dialog can be used to inform the user about questions and get
+/// the answer.
+///
+/// In order to achieve a line break is a <b>\\n</b> directly in the text or
+/// in the <em>"./resources/language/resource.language.??_??/strings.po"</em>
+/// to call with <b>std::string kodi::general::GetLocalizedString(...);</b>.
+///
+/// It has the header @ref YesNo.h "#include <kodi/gui/dialogs/YesNo.h>"
+/// be included to enjoy it.
+///
+namespace YesNo
+{
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_YesNo
+/// @brief Use dialog to get numeric new password with one text string shown
+/// everywhere and cancel return field.
+///
+/// @param[in] heading Dialog heading
+/// @param[in] text Multi-line text
+/// @param[out] canceled Return value about cancel button
+/// @param[in] noLabel [opt] label to put on the no button
+/// @param[in] yesLabel [opt] label to put on the yes button
+/// @return Returns True if 'Yes' was pressed, else False
+///
+/// @note It is preferred to only use this as it is actually a multi-line text.
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/YesNo.h>
+///
+/// bool canceled = false;
+/// bool ret = kodi::gui::dialogs::YesNo::ShowAndGetInput(
+/// "Yes / No test call", // The Header
+/// "You has opened Yes / No dialog for test\n\nIs this OK for you?",
+/// canceled, // return value about cancel button
+/// "Not really", // No label, is optional and if empty "No"
+/// "Ohhh yes"); // Yes label, also optional and if empty "Yes"
+/// fprintf(stderr, "You has called Yes/No, returned '%s' and was %s\n",
+/// ret ? "yes" : "no",
+/// canceled ? "canceled" : "not canceled");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetInput(const std::string& heading,
+ const std::string& text,
+ bool& canceled,
+ const std::string& noLabel = "",
+ const std::string& yesLabel = "")
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_single_text(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), text.c_str(), &canceled,
+ noLabel.c_str(), yesLabel.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_YesNo
+/// @brief Use dialog to get numeric new password with separated line strings.
+///
+/// @param[in] heading Dialog heading
+/// @param[in] line0 Line #0 text
+/// @param[in] line1 Line #1 text
+/// @param[in] line2 Line #2 text
+/// @param[in] noLabel [opt] label to put on the no button
+/// @param[in] yesLabel [opt] label to put on the yes button
+/// @return Returns True if 'Yes' was pressed, else False
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/YesNo.h>
+///
+/// bool ret = kodi::gui::dialogs::YesNo::ShowAndGetInput(
+/// "Yes / No test call", // The Header
+/// "You has opened Yes / No dialog for test",
+/// "",
+/// "Is this OK for you?",
+/// "Not really", // No label, is optional and if empty "No"
+/// "Ohhh yes"); // Yes label, also optional and if empty "Yes"
+/// fprintf(stderr, "You has called Yes/No, returned '%s'\n",
+/// ret ? "yes" : "no");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetInput(const std::string& heading,
+ const std::string& line0,
+ const std::string& line1,
+ const std::string& line2,
+ const std::string& noLabel = "",
+ const std::string& yesLabel = "")
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_text(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), line0.c_str(), line1.c_str(),
+ line2.c_str(), noLabel.c_str(), yesLabel.c_str());
+}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_YesNo
+/// @brief Use dialog to get numeric new password with separated line strings
+/// and cancel return field.
+///
+/// @param[in] heading Dialog heading
+/// @param[in] line0 Line #0 text
+/// @param[in] line1 Line #1 text
+/// @param[in] line2 Line #2 text
+/// @param[out] canceled Return value about cancel button
+/// @param[in] noLabel [opt] label to put on the no button
+/// @param[in] yesLabel [opt] label to put on the yes button
+/// @return Returns True if 'Yes' was pressed, else False
+///
+///
+///-------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/gui/dialogs/YesNo.h>
+///
+/// bool canceled = false;
+/// bool ret = kodi::gui::dialogs::YesNo::ShowAndGetInput(
+/// "Yes / No test call", // The Header
+/// "You has opened Yes / No dialog for test",
+/// "",
+/// "Is this OK for you?",
+/// canceled, // return value about cancel button
+/// "Not really", // No label, is optional and if empty "No"
+/// "Ohhh yes"); // Yes label, also optional and if empty "Yes"
+/// fprintf(stderr, "You has called Yes/No, returned '%s' and was %s\n",
+/// ret ? "yes" : "no",
+/// canceled ? "canceled" : "not canceled");
+/// ~~~~~~~~~~~~~
+///
+inline bool ATTR_DLL_LOCAL ShowAndGetInput(const std::string& heading,
+ const std::string& line0,
+ const std::string& line1,
+ const std::string& line2,
+ bool& canceled,
+ const std::string& noLabel = "",
+ const std::string& yesLabel = "")
+{
+ using namespace ::kodi::addon;
+ return CPrivateBase::m_interface->toKodi->kodi_gui->dialogYesNo
+ ->show_and_get_input_line_button_text(
+ CPrivateBase::m_interface->toKodi->kodiBase, heading.c_str(), line0.c_str(),
+ line1.c_str(), line2.c_str(), &canceled, noLabel.c_str(), yesLabel.c_str());
+}
+//------------------------------------------------------------------------------
+}; // namespace YesNo
+/// @}
+
+} /* namespace dialogs */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/CMakeLists.txt
new file mode 100644
index 0000000..36b823c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ GL.h
+ GLonDX.h
+ Shader.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_gui_gl)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h
new file mode 100644
index 0000000..16d43e3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2005-2019 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+//==============================================================================
+/// @defgroup cpp_kodi_gui_helpers_gl OpenGL helpers
+/// @ingroup cpp_kodi_gui_helpers
+/// @brief **Auxiliary functions for Open GL**\n
+/// This group includes help for definitions, functions, and classes for
+/// OpenGL.
+///
+/// To use OpenGL for your system, add the @ref GL.h "#include <kodi/gui/gl/GL.h>".
+///
+/// The @ref HAS_GL is declared if Open GL is required and @ref HAS_GLES if Open GL
+/// Embedded Systems (ES) is required, with ES the version is additionally given
+/// in the definition, this can be "2" or "3".
+///
+///
+///-----------------------------------------------------------------------------
+///
+/// Following @ref GL_TYPE_STRING define can be used, for example, to manage
+/// different folders for GL and GLES and make the selection easier.
+/// This are on OpenGL <b>"GL"</b> and on Open GL|ES <b>"GLES"</b>.
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~~~~~{.cpp}
+/// kodi::GetAddonPath("resources/shaders/" GL_TYPE_STRING "/frag.glsl");
+/// ~~~~~~~~~~~~~~~~~
+///
+///
+///----------------------------------------------------------------------------
+///
+/// In addition, @ref BUFFER_OFFSET is declared in it which can be used to give an
+/// offset on the array to GL.
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~~~~~{.cpp}
+/// const struct PackedVertex {
+/// float position[3]; // Position x, y, z
+/// float color[4]; // Color r, g, b, a
+/// } vertices[3] = {
+/// { { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
+/// { { 0.5f, -0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
+/// { { 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }
+/// };
+///
+/// glVertexAttribPointer(m_aPosition, 3, GL_FLOAT, GL_FALSE, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, position)));
+/// glEnableVertexAttribArray(m_aPosition);
+///
+/// glVertexAttribPointer(m_aColor, 4, GL_FLOAT, GL_FALSE, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, color)));
+/// glEnableVertexAttribArray(m_aColor);
+/// ~~~~~~~~~~~~~~~~~
+
+#if HAS_GL
+#define GL_TYPE_STRING "GL"
+// always define GL_GLEXT_PROTOTYPES before include gl headers
+#if !defined(GL_GLEXT_PROTOTYPES)
+#define GL_GLEXT_PROTOTYPES
+#endif
+#if defined(TARGET_LINUX)
+#include <GL/gl.h>
+#include <GL/glext.h>
+#elif defined(TARGET_FREEBSD)
+#include <GL/gl.h>
+#elif defined(TARGET_DARWIN)
+#include <OpenGL/gl3.h>
+#include <OpenGL/gl3ext.h>
+#elif defined(WIN32)
+#error Use of GL under Windows is not possible
+#endif
+#elif HAS_GLES >= 2
+#define GL_TYPE_STRING "GLES"
+#if defined(WIN32)
+#if defined(HAS_ANGLE)
+#include <angle_gl.h>
+#else
+#error Use of GLES only be available under Windows by the use of angle
+#endif
+#elif defined(TARGET_DARWIN)
+#if HAS_GLES == 3
+#include <OpenGLES/ES3/gl.h>
+#include <OpenGLES/ES3/glext.h>
+#else
+#include <OpenGLES/ES2/gl.h>
+#include <OpenGLES/ES2/glext.h>
+#endif
+#else
+#if HAS_GLES == 3
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+#else
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#endif
+#endif
+#endif
+
+#ifndef BUFFER_OFFSET
+/// @ingroup cpp_kodi_gui_helpers_gl
+/// @brief To give a offset number as pointer value.
+#define BUFFER_OFFSET(i) ((char*)nullptr + (i))
+#endif
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GLonDX.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GLonDX.h
new file mode 100644
index 0000000..9ba76ea
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GLonDX.h
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2005-2019 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+#if defined(WIN32) && defined(HAS_ANGLE)
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <angle_gl.h>
+#include <d3d11.h>
+#include <d3dcompiler.h>
+#include <kodi/AddonBase.h>
+#include <kodi/gui/General.h>
+#include <wrl/client.h>
+
+#pragma comment(lib, "d3dcompiler.lib")
+#ifndef GL_CLIENT_VERSION
+#define GL_CLIENT_VERSION 3
+#endif
+
+namespace kodi
+{
+namespace gui
+{
+namespace gl
+{
+
+class ATTR_DLL_LOCAL CGLonDX : public kodi::gui::IRenderHelper
+{
+public:
+ explicit CGLonDX() : m_pContext(reinterpret_cast<ID3D11DeviceContext*>(kodi::gui::GetHWContext()))
+ {
+ }
+ ~CGLonDX() override { destruct(); }
+
+ bool Init() override
+ {
+ EGLint egl_display_attrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+ EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
+ EGL_DONT_CARE,
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
+ EGL_DONT_CARE,
+ EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
+ EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
+ EGL_NONE};
+ EGLint egl_config_attrs[] = {EGL_RED_SIZE,
+ 8,
+ EGL_GREEN_SIZE,
+ 8,
+ EGL_BLUE_SIZE,
+ 8,
+ EGL_ALPHA_SIZE,
+ 8,
+ EGL_BIND_TO_TEXTURE_RGBA,
+ EGL_TRUE,
+ EGL_RENDERABLE_TYPE,
+ GL_CLIENT_VERSION == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE,
+ EGL_PBUFFER_BIT,
+ EGL_NONE};
+ EGLint egl_context_attrs[] = {EGL_CONTEXT_CLIENT_VERSION, GL_CLIENT_VERSION, EGL_NONE};
+
+ m_eglDisplay =
+ eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, egl_display_attrs);
+ if (m_eglDisplay == EGL_NO_DISPLAY)
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to get EGL display (%s)", eglGetErrorString());
+ return false;
+ }
+
+ if (eglInitialize(m_eglDisplay, nullptr, nullptr) != EGL_TRUE)
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to init EGL display (%s)", eglGetErrorString());
+ return false;
+ }
+
+ EGLint numConfigs = 0;
+ if (eglChooseConfig(m_eglDisplay, egl_config_attrs, &m_eglConfig, 1, &numConfigs) != EGL_TRUE ||
+ numConfigs == 0)
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to get EGL config (%s)", eglGetErrorString());
+ return false;
+ }
+
+ m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, nullptr, egl_context_attrs);
+ if (m_eglContext == EGL_NO_CONTEXT)
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to create EGL context (%s)", eglGetErrorString());
+ return false;
+ }
+
+ if (!createD3DResources())
+ return false;
+
+ if (eglMakeCurrent(m_eglDisplay, m_eglBuffer, m_eglBuffer, m_eglContext) != EGL_TRUE)
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to make current EGL (%s)", eglGetErrorString());
+ return false;
+ }
+ return true;
+ }
+
+ void CheckGL(ID3D11DeviceContext* device)
+ {
+ if (m_pContext != device)
+ {
+ m_pSRView = nullptr;
+ m_pVShader = nullptr;
+ m_pPShader = nullptr;
+ m_pContext = device;
+
+ if (m_eglBuffer != EGL_NO_SURFACE)
+ {
+ eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(m_eglDisplay, m_eglBuffer);
+ m_eglBuffer = EGL_NO_SURFACE;
+ }
+
+ // create new resources
+ if (!createD3DResources())
+ return;
+
+ eglMakeCurrent(m_eglDisplay, m_eglBuffer, m_eglBuffer, m_eglContext);
+ }
+ }
+
+ void Begin() override
+ {
+ // confirm on begin D3D context is correct
+ CheckGL(reinterpret_cast<ID3D11DeviceContext*>(kodi::gui::GetHWContext()));
+
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ void End() override
+ {
+ glFlush();
+
+ // set our primitive shaders
+ m_pContext->VSSetShader(m_pVShader.Get(), nullptr, 0);
+ m_pContext->PSSetShader(m_pPShader.Get(), nullptr, 0);
+ m_pContext->PSSetShaderResources(0, 1, m_pSRView.GetAddressOf());
+ // draw texture
+ m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ m_pContext->IASetVertexBuffers(0, 0, nullptr, nullptr, nullptr);
+ m_pContext->IASetInputLayout(nullptr);
+ m_pContext->Draw(4, 0);
+ // unset shaders
+ m_pContext->PSSetShader(nullptr, nullptr, 0);
+ m_pContext->VSSetShader(nullptr, nullptr, 0);
+ // unbind our view
+ ID3D11ShaderResourceView* views[1] = {};
+ m_pContext->PSSetShaderResources(0, 1, views);
+ }
+
+private:
+ enum ShaderType
+ {
+ VERTEX_SHADER,
+ PIXEL_SHADER
+ };
+
+ bool createD3DResources()
+ {
+ HANDLE sharedHandle;
+ Microsoft::WRL::ComPtr<ID3D11Device> pDevice;
+ Microsoft::WRL::ComPtr<ID3D11RenderTargetView> pRTView;
+ Microsoft::WRL::ComPtr<ID3D11Resource> pRTResource;
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> pRTTexture;
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> pOffScreenTexture;
+ Microsoft::WRL::ComPtr<IDXGIResource> dxgiResource;
+
+ m_pContext->GetDevice(&pDevice);
+ m_pContext->OMGetRenderTargets(1, &pRTView, nullptr);
+ if (!pRTView)
+ return false;
+
+ pRTView->GetResource(&pRTResource);
+ if (FAILED(pRTResource.As(&pRTTexture)))
+ return false;
+
+ D3D11_TEXTURE2D_DESC texDesc;
+ pRTTexture->GetDesc(&texDesc);
+ texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
+ if (FAILED(pDevice->CreateTexture2D(&texDesc, nullptr, &pOffScreenTexture)))
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to create intermediate texture");
+ return false;
+ }
+
+ CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc(pOffScreenTexture.Get(),
+ D3D11_SRV_DIMENSION_TEXTURE2D);
+ if (FAILED(pDevice->CreateShaderResourceView(pOffScreenTexture.Get(), &srvDesc, &m_pSRView)))
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to create shader view");
+ return false;
+ }
+
+ if (FAILED(pOffScreenTexture.As(&dxgiResource)) ||
+ FAILED(dxgiResource->GetSharedHandle(&sharedHandle)))
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable get shared handle for texture");
+ return false;
+ }
+
+ // initiate simple shaders
+ if (FAILED(d3dCreateShader(VERTEX_SHADER, vs_out_shader_text, &m_pVShader)))
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to create vertex shader view");
+ return false;
+ }
+
+ if (FAILED(d3dCreateShader(PIXEL_SHADER, ps_out_shader_text, &m_pPShader)))
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to create pixel shader view");
+ return false;
+ }
+
+ // create EGL buffer from D3D shared texture
+ EGLint egl_buffer_attrs[] = {EGL_WIDTH,
+ static_cast<EGLint>(texDesc.Width),
+ EGL_HEIGHT,
+ static_cast<EGLint>(texDesc.Height),
+ EGL_TEXTURE_TARGET,
+ EGL_TEXTURE_2D,
+ EGL_TEXTURE_FORMAT,
+ EGL_TEXTURE_RGBA,
+ EGL_NONE};
+
+ m_eglBuffer =
+ eglCreatePbufferFromClientBuffer(m_eglDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
+ sharedHandle, m_eglConfig, egl_buffer_attrs);
+
+ if (m_eglBuffer == EGL_NO_SURFACE)
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to create EGL buffer (%s)", eglGetErrorString());
+ return false;
+ }
+ return true;
+ }
+
+ HRESULT d3dCreateShader(ShaderType shaderType,
+ const std::string& source,
+ IUnknown** ppShader) const
+ {
+ Microsoft::WRL::ComPtr<ID3DBlob> pBlob;
+ Microsoft::WRL::ComPtr<ID3DBlob> pErrors;
+
+ auto hr = D3DCompile(source.c_str(), source.length(), nullptr, nullptr, nullptr, "main",
+ shaderType == PIXEL_SHADER ? "ps_4_0" : "vs_4_0", 0, 0, &pBlob, &pErrors);
+
+ if (SUCCEEDED(hr))
+ {
+ Microsoft::WRL::ComPtr<ID3D11Device> pDevice;
+ m_pContext->GetDevice(&pDevice);
+
+ if (shaderType == PIXEL_SHADER)
+ {
+ hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr,
+ reinterpret_cast<ID3D11PixelShader**>(ppShader));
+ }
+ else
+ {
+ hr = pDevice->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr,
+ reinterpret_cast<ID3D11VertexShader**>(ppShader));
+ }
+
+ if (FAILED(hr))
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to create %s shader",
+ shaderType == PIXEL_SHADER ? "pixel" : "vertex");
+ }
+ }
+ else
+ {
+ Log(ADDON_LOG_ERROR, "GLonDX: unable to compile shader (%s)", pErrors->GetBufferPointer());
+ }
+ return hr;
+ }
+
+ static const char* eglGetErrorString()
+ {
+#define CASE_STR(value) \
+ case value: \
+ return #value
+ switch (eglGetError())
+ {
+ CASE_STR(EGL_SUCCESS);
+ CASE_STR(EGL_NOT_INITIALIZED);
+ CASE_STR(EGL_BAD_ACCESS);
+ CASE_STR(EGL_BAD_ALLOC);
+ CASE_STR(EGL_BAD_ATTRIBUTE);
+ CASE_STR(EGL_BAD_CONTEXT);
+ CASE_STR(EGL_BAD_CONFIG);
+ CASE_STR(EGL_BAD_CURRENT_SURFACE);
+ CASE_STR(EGL_BAD_DISPLAY);
+ CASE_STR(EGL_BAD_SURFACE);
+ CASE_STR(EGL_BAD_MATCH);
+ CASE_STR(EGL_BAD_PARAMETER);
+ CASE_STR(EGL_BAD_NATIVE_PIXMAP);
+ CASE_STR(EGL_BAD_NATIVE_WINDOW);
+ CASE_STR(EGL_CONTEXT_LOST);
+ default:
+ return "Unknown";
+ }
+#undef CASE_STR
+ }
+
+ void destruct()
+ {
+ if (m_eglDisplay != EGL_NO_DISPLAY)
+ {
+ eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (m_eglBuffer != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(m_eglDisplay, m_eglBuffer);
+ m_eglBuffer = EGL_NO_SURFACE;
+ }
+
+ if (m_eglContext != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
+ }
+
+ eglTerminate(m_eglDisplay);
+ m_eglDisplay = EGL_NO_DISPLAY;
+ }
+
+ m_pSRView = nullptr;
+ m_pVShader = nullptr;
+ m_pPShader = nullptr;
+ m_pContext = nullptr;
+ }
+
+ EGLConfig m_eglConfig = EGL_NO_CONFIG_KHR;
+ EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
+ EGLContext m_eglContext = EGL_NO_CONTEXT;
+ EGLSurface m_eglBuffer = EGL_NO_SURFACE;
+
+ ID3D11DeviceContext* m_pContext = nullptr; // don't hold context
+ Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_pSRView = nullptr;
+ Microsoft::WRL::ComPtr<ID3D11VertexShader> m_pVShader = nullptr;
+ Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pPShader = nullptr;
+
+#define TO_STRING(...) #__VA_ARGS__
+ std::string vs_out_shader_text = TO_STRING(void main(uint id
+ : SV_VertexId, out float2 tex
+ : TEXCOORD0, out float4 pos
+ : SV_POSITION) {
+ tex = float2(id % 2, (id % 4) >> 1);
+ pos = float4((tex.x - 0.5f) * 2, -(tex.y - 0.5f) * 2, 0, 1);
+ });
+
+ std::string ps_out_shader_text = TO_STRING(
+ Texture2D texMain : register(t0);
+ SamplerState Sampler
+ {
+ Filter = MIN_MAG_MIP_LINEAR;
+ AddressU = CLAMP;
+ AddressV = CLAMP;
+ Comparison = NEVER;
+ };
+
+ float4 main(in float2 tex : TEXCOORD0) : SV_TARGET
+ {
+ return texMain.Sample(Sampler, tex);
+ });
+#undef TO_STRING
+}; /* class CGLonDX */
+
+} /* namespace gl */
+
+using CRenderHelper = gl::CGLonDX;
+} /* namespace gui */
+} /* namespace kodi */
+
+#else /* defined(WIN32) && defined(HAS_ANGLE) */
+#pragma message ( "WARNING: GLonDX.h only be available on Windows by use of Angle as depend!" )
+#endif /* defined(WIN32) && defined(HAS_ANGLE) */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/Shader.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/Shader.h
new file mode 100644
index 0000000..ae78b7c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/Shader.h
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2005-2019 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.
+ */
+
+#pragma once
+
+#include "GL.h"
+
+#ifdef __cplusplus
+
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+#include <kodi/AddonBase.h>
+#include <kodi/Filesystem.h>
+
+#define LOG_SIZE 1024
+#define GLchar char
+
+namespace kodi
+{
+namespace gui
+{
+namespace gl
+{
+
+//========================================================================
+/// CShader - base class
+class ATTR_DLL_LOCAL CShader
+{
+public:
+ CShader() = default;
+ virtual ~CShader() = default;
+ virtual bool Compile(const std::string& extraBegin = "", const std::string& extraEnd = "") = 0;
+ virtual void Free() = 0;
+ virtual GLuint Handle() = 0;
+
+ bool LoadSource(const std::string& file)
+ {
+ char buffer[16384];
+
+ kodi::vfs::CFile source;
+ if (!source.OpenFile(file))
+ {
+ kodi::Log(ADDON_LOG_ERROR, "CShader::%s: Failed to open file '%s'", __FUNCTION__,
+ file.c_str());
+ return false;
+ }
+ size_t len = source.Read(buffer, sizeof(buffer));
+ m_source.assign(buffer);
+ m_source[len] = 0;
+ source.Close();
+ return true;
+ }
+
+ bool OK() const { return m_compiled; }
+
+protected:
+ std::string m_source;
+ std::string m_lastLog;
+ bool m_compiled = false;
+};
+//------------------------------------------------------------------------
+
+//========================================================================
+/// CVertexShader
+class ATTR_DLL_LOCAL CVertexShader : public CShader
+{
+public:
+ CVertexShader() = default;
+ ~CVertexShader() override { Free(); }
+
+ void Free() override
+ {
+ if (m_vertexShader)
+ glDeleteShader(m_vertexShader);
+ m_vertexShader = 0;
+ }
+
+ bool Compile(const std::string& extraBegin = "", const std::string& extraEnd = "") override
+ {
+ GLint params[4];
+
+ Free();
+
+ m_vertexShader = glCreateShader(GL_VERTEX_SHADER);
+
+ GLsizei count = 0;
+ const char* sources[3];
+ if (!extraBegin.empty())
+ sources[count++] = extraBegin.c_str();
+ if (!m_source.empty())
+ sources[count++] = m_source.c_str();
+ if (!extraEnd.empty())
+ sources[count++] = extraEnd.c_str();
+
+ glShaderSource(m_vertexShader, count, sources, nullptr);
+ glCompileShader(m_vertexShader);
+ glGetShaderiv(m_vertexShader, GL_COMPILE_STATUS, params);
+ if (params[0] != GL_TRUE)
+ {
+ GLchar log[LOG_SIZE];
+ glGetShaderInfoLog(m_vertexShader, LOG_SIZE, nullptr, log);
+ kodi::Log(ADDON_LOG_ERROR, "CVertexShader::%s: %s", __FUNCTION__, log);
+ fprintf(stderr, "CVertexShader::%s: %s\n", __FUNCTION__, log);
+ m_lastLog = log;
+ m_compiled = false;
+ }
+ else
+ {
+ GLchar log[LOG_SIZE];
+ glGetShaderInfoLog(m_vertexShader, LOG_SIZE, nullptr, log);
+ m_lastLog = log;
+ m_compiled = true;
+ }
+ return m_compiled;
+ }
+
+ GLuint Handle() override { return m_vertexShader; }
+
+protected:
+ GLuint m_vertexShader = 0;
+};
+//------------------------------------------------------------------------
+
+//========================================================================
+/// CPixelShader
+class ATTR_DLL_LOCAL CPixelShader : public CShader
+{
+public:
+ CPixelShader() = default;
+ ~CPixelShader() { Free(); }
+ void Free() override
+ {
+ if (m_pixelShader)
+ glDeleteShader(m_pixelShader);
+ m_pixelShader = 0;
+ }
+
+ bool Compile(const std::string& extraBegin = "", const std::string& extraEnd = "") override
+ {
+ GLint params[4];
+
+ Free();
+
+ m_pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
+
+ GLsizei count = 0;
+ const char* sources[3];
+ if (!extraBegin.empty())
+ sources[count++] = extraBegin.c_str();
+ if (!m_source.empty())
+ sources[count++] = m_source.c_str();
+ if (!extraEnd.empty())
+ sources[count++] = extraEnd.c_str();
+
+ glShaderSource(m_pixelShader, count, sources, 0);
+ glCompileShader(m_pixelShader);
+ glGetShaderiv(m_pixelShader, GL_COMPILE_STATUS, params);
+ if (params[0] != GL_TRUE)
+ {
+ GLchar log[LOG_SIZE];
+ glGetShaderInfoLog(m_pixelShader, LOG_SIZE, nullptr, log);
+ kodi::Log(ADDON_LOG_ERROR, "CPixelShader::%s: %s", __FUNCTION__, log);
+ fprintf(stderr, "CPixelShader::%s: %s\n", __FUNCTION__, log);
+ m_lastLog = log;
+ m_compiled = false;
+ }
+ else
+ {
+ GLchar log[LOG_SIZE];
+ glGetShaderInfoLog(m_pixelShader, LOG_SIZE, nullptr, log);
+ m_lastLog = log;
+ m_compiled = true;
+ }
+ return m_compiled;
+ }
+
+ GLuint Handle() override { return m_pixelShader; }
+
+protected:
+ GLuint m_pixelShader = 0;
+};
+//------------------------------------------------------------------------
+
+//============================================================================
+/// @defgroup cpp_kodi_gui_helpers_gl_CShaderProgram GL Shader Program
+/// @ingroup cpp_kodi_gui_helpers_gl
+/// @brief @cpp_class{ kodi::gui::gl::CShaderProgram }
+/// **Class to manage an OpenGL shader program**\n
+/// With this class the used GL shader code can be defined on the GPU and
+/// its variables can be managed between CPU and GPU.
+///
+/// It has the header @ref Shader.h "#include <kodi/gui/gl/Shader.h>"
+/// be included to enjoy it.
+///
+/// ----------------------------------------------------------------------------
+///
+/// <b>Example:</b>
+///
+/// ~~~~~~~~~~~~~{.cpp}
+///
+/// #include <kodi/gui/gl/Shader.h>
+/// ...
+///
+/// class ATTR_DLL_LOCAL CExample
+/// : ...,
+/// public kodi::gui::gl::CShaderProgram
+/// {
+/// public:
+/// CExample() = default;
+///
+/// bool Start();
+/// void Render();
+///
+/// // override functions for kodi::gui::gl::CShaderProgram
+/// void OnCompiledAndLinked() override;
+/// bool OnEnabled() override;
+///
+/// private:
+/// ...
+/// GLint m_aPosition = -1;
+/// GLint m_aColor = -1;
+/// };
+///
+/// bool CExample::Start()
+/// {
+/// // Define shaders and load
+/// std::string fraqShader = kodi::GetAddonPath("resources/shaders/" GL_TYPE_STRING "/glsl.frag");
+/// std::string vertShader = kodi::GetAddonPath("resources/shaders/" GL_TYPE_STRING "/glsl.vert");
+/// if (!LoadShaderFiles(vertShader, fraqShader) || !CompileAndLink())
+/// return false;
+///
+/// ...
+/// return true;
+/// }
+///
+/// ...
+///
+/// void CExample::Render()
+/// {
+/// ...
+///
+/// EnableShader();
+/// ...
+/// DO WORK
+/// ...
+/// DisableShader();
+/// }
+///
+/// void CExample::OnCompiledAndLinked()
+/// {
+/// ...
+/// DO YOUR WORK HERE FOR WHAT IS ONE TIME REQUIRED DURING COMPILE OF SHADER, E.G.:
+///
+/// m_aPosition = glGetAttribLocation(ProgramHandle(), "a_position");
+/// m_aColor = glGetAttribLocation(ProgramHandle(), "a_color");
+/// }
+///
+/// bool OnEnabled() override
+/// {
+/// ...
+/// DO YOUR WORK HERE FOR WHAT REQUIRED DURING ENABLE OF SHADER
+/// ...
+/// return true;
+/// }
+///
+/// ADDONCREATOR(CExample);
+/// ~~~~~~~~~~~~~
+///
+class ATTR_DLL_LOCAL CShaderProgram
+{
+public:
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief Construct a new shader.
+ ///
+ /// Load must be done later with @ref LoadShaderFiles.
+ ///
+ CShaderProgram() = default;
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief Construct a new shader and load defined shader files.
+ ///
+ /// @param[in] vert Path to used GL vertext shader
+ /// @param[in] frag Path to used GL fragment shader
+ ///
+ CShaderProgram(const std::string& vert, const std::string& frag) { LoadShaderFiles(vert, frag); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief Destructor.
+ ///
+ virtual ~CShaderProgram() { ShaderFree(); }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To load manually the needed shader files.
+ ///
+ /// @param[in] vert Path to used GL vertext shader
+ /// @param[in] frag Path to used GL fragment shader
+ ///
+ ///
+ /// @note The use of the files is optional, but it must either be passed over
+ /// here or via @ref CompileAndLink, or both of the source code.
+ ///
+ bool LoadShaderFiles(const std::string& vert, const std::string& frag)
+ {
+ if (!kodi::vfs::FileExists(vert) || !m_pVP.LoadSource(vert))
+ {
+ kodi::Log(ADDON_LOG_ERROR, "%s: Failed to load '%s'", __func__, vert.c_str());
+ return false;
+ }
+
+ if (!kodi::vfs::FileExists(frag) || !m_pFP.LoadSource(frag))
+ {
+ kodi::Log(ADDON_LOG_ERROR, "%s: Failed to load '%s'", __func__, frag.c_str());
+ return false;
+ }
+
+ return true;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To compile and link the shader to the GL interface.
+ ///
+ /// Optionally, additional source code can be transferred here, or it can be
+ /// used independently without any files
+ ///
+ /// @param[in] vertexExtraBegin [opt] To additionally add vextex source
+ /// code to the beginning of the loaded file
+ /// source code
+ /// @param[in] vertexExtraEnd [opt] To additionally add vextex source
+ /// code to the end of the loaded file
+ /// source code
+ /// @param[in] fragmentExtraBegin [opt] To additionally add fragment source
+ /// code to the beginning of the loaded file
+ /// source code
+ /// @param[in] fragmentExtraEnd [opt] To additionally add fragment source
+ /// code to the end of the loaded file
+ /// source code
+ /// @return true if compile was successed
+ ///
+ ///
+ /// @note In the case of a compile error, it will be written once into the Kodi
+ /// log and in addition to the console output to quickly detect the errors when
+ /// writing the damage.
+ ///
+ ///
+ bool CompileAndLink(const std::string& vertexExtraBegin = "",
+ const std::string& vertexExtraEnd = "",
+ const std::string& fragmentExtraBegin = "",
+ const std::string& fragmentExtraEnd = "")
+ {
+ GLint params[4];
+
+ // free resources
+ ShaderFree();
+ m_ok = false;
+
+ // compiled vertex shader
+ if (!m_pVP.Compile(vertexExtraBegin, vertexExtraEnd))
+ {
+ kodi::Log(ADDON_LOG_ERROR, "GL: Error compiling vertex shader");
+ return false;
+ }
+
+ // compile pixel shader
+ if (!m_pFP.Compile(fragmentExtraBegin, fragmentExtraEnd))
+ {
+ m_pVP.Free();
+ kodi::Log(ADDON_LOG_ERROR, "GL: Error compiling fragment shader");
+ return false;
+ }
+
+ // create program object
+ m_shaderProgram = glCreateProgram();
+ if (!m_shaderProgram)
+ {
+ kodi::Log(ADDON_LOG_ERROR, "CShaderProgram::%s: Failed to create GL program", __FUNCTION__);
+ ShaderFree();
+ return false;
+ }
+
+ // attach the vertex shader
+ glAttachShader(m_shaderProgram, m_pVP.Handle());
+ glAttachShader(m_shaderProgram, m_pFP.Handle());
+
+ // link the program
+ glLinkProgram(m_shaderProgram);
+ glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, params);
+ if (params[0] != GL_TRUE)
+ {
+ GLchar log[LOG_SIZE];
+ glGetProgramInfoLog(m_shaderProgram, LOG_SIZE, nullptr, log);
+ kodi::Log(ADDON_LOG_ERROR, "CShaderProgram::%s: %s", __FUNCTION__, log);
+ fprintf(stderr, "CShaderProgram::%s: %s@n", __FUNCTION__, log);
+ ShaderFree();
+ return false;
+ }
+
+ m_validated = false;
+ m_ok = true;
+ OnCompiledAndLinked();
+ return true;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To activate the shader and use it on the GPU.
+ ///
+ /// @return true if enable was successfully done
+ ///
+ ///
+ /// @note During this call, the @ref OnEnabled stored in the child is also
+ /// called
+ ///
+ bool EnableShader()
+ {
+ if (ShaderOK())
+ {
+ glUseProgram(m_shaderProgram);
+ if (OnEnabled())
+ {
+ if (!m_validated)
+ {
+ // validate the program
+ GLint params[4];
+ glValidateProgram(m_shaderProgram);
+ glGetProgramiv(m_shaderProgram, GL_VALIDATE_STATUS, params);
+ if (params[0] != GL_TRUE)
+ {
+ GLchar log[LOG_SIZE];
+ glGetProgramInfoLog(m_shaderProgram, LOG_SIZE, nullptr, log);
+ kodi::Log(ADDON_LOG_ERROR, "CShaderProgram::%s: %s", __FUNCTION__, log);
+ fprintf(stderr, "CShaderProgram::%s: %s\n", __FUNCTION__, log);
+ }
+ m_validated = true;
+ }
+ return true;
+ }
+ else
+ {
+ glUseProgram(0);
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To deactivate the shader use on the GPU.
+ ///
+ void DisableShader()
+ {
+ if (ShaderOK())
+ {
+ glUseProgram(0);
+ OnDisabled();
+ }
+ }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief Used to check if shader has been loaded before.
+ ///
+ /// @return true if enable was successfully done
+ ///
+ /// @note The CompileAndLink call sets these values
+ ///
+ ATTR_FORCEINLINE bool ShaderOK() const { return m_ok; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To get the vertex shader class used by Kodi at the addon.
+ ///
+ /// @return pointer to vertex shader class
+ ///
+ ATTR_FORCEINLINE CVertexShader& VertexShader() { return m_pVP; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To get the fragment shader class used by Kodi at the addon.
+ ///
+ /// @return pointer to fragment shader class
+ ///
+ ATTR_FORCEINLINE CPixelShader& PixelShader() { return m_pFP; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief Used to get the definition created in the OpenGL itself.
+ ///
+ /// @return GLuint of GL shader program handler
+ ///
+ ATTR_FORCEINLINE GLuint ProgramHandle() { return m_shaderProgram; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @defgroup cpp_kodi_gui_helpers_gl_CShaderProgram_child Child Functions
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief @cpp_class{ kodi::gui::gl::CShaderProgram child functions }
+ ///
+ /// Functions that are added by parent in the child
+ /// @{
+ //==========================================================================
+ ///
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram_child
+ /// @brief Mandatory child function to set the necessary CPU to GPU data
+ ///
+ virtual void OnCompiledAndLinked() {}
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram_child
+ /// @brief Optional function to exchange data between CPU and GPU while
+ /// activating the shader
+ ///
+ /// @return true if enable was successfully done
+ ///
+ virtual bool OnEnabled() { return true; }
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram_child
+ /// @brief Optional child function that may have to be performed when
+ /// switching off the shader
+ virtual void OnDisabled() {}
+ //--------------------------------------------------------------------------
+ /// @}
+
+private:
+ void ShaderFree()
+ {
+ if (m_shaderProgram)
+ glDeleteProgram(m_shaderProgram);
+ m_shaderProgram = 0;
+ m_ok = false;
+ }
+
+ CVertexShader m_pVP;
+ CPixelShader m_pFP;
+ GLuint m_shaderProgram = 0;
+ bool m_ok = false;
+ bool m_validated = false;
+};
+//------------------------------------------------------------------------
+
+} /* namespace gl */
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/input/ActionIDs.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/input/ActionIDs.h
new file mode 100644
index 0000000..4c816a4
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/input/ActionIDs.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#include "../../c-api/gui/input/action_ids.h"
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/input/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/gui/input/CMakeLists.txt
new file mode 100644
index 0000000..769cad2
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/input/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ ActionIDs.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_gui_input)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/renderHelper.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/renderHelper.h
new file mode 100644
index 0000000..f369205
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/renderHelper.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2005-2019 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.
+ */
+
+#pragma once
+
+#include "../AddonBase.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+struct ATTR_DLL_LOCAL IRenderHelper
+{
+ virtual ~IRenderHelper() = default;
+ virtual bool Init() = 0;
+ virtual void Begin() = 0;
+ virtual void End() = 0;
+}; /* class IRenderHelper */
+} /* namespace gui */
+} /* namespace kodi */
+
+#if defined(WIN32) && defined(HAS_ANGLE)
+#include "gl/GLonDX.h"
+#else
+/*
+ * Default background GUI render helper class
+ */
+namespace kodi
+{
+namespace gui
+{
+struct ATTR_DLL_LOCAL CRenderHelperStub : public IRenderHelper
+{
+ bool Init() override { return true; }
+ void Begin() override {}
+ void End() override {}
+}; /* class CRenderHelperStub */
+
+using CRenderHelper = CRenderHelperStub;
+} /* namespace gui */
+} /* namespace kodi */
+#endif
+
+namespace kodi
+{
+namespace gui
+{
+
+/*
+ * Create render background handler, e.g. becomes on "Windows" Angle used
+ * to emulate GL.
+ *
+ * This only be used internal and not from addon's direct.
+ *
+ * Function defines here and not in CAddonBase because of a hen and egg problem.
+ */
+inline std::shared_ptr<IRenderHelper> ATTR_DLL_LOCAL GetRenderHelper()
+{
+ using namespace ::kodi::addon;
+ if (static_cast<CAddonBase*>(CPrivateBase::m_interface->addonBase)->m_renderHelper)
+ return static_cast<CAddonBase*>(CPrivateBase::m_interface->addonBase)->m_renderHelper;
+
+ std::shared_ptr<kodi::gui::IRenderHelper> renderHelper(new CRenderHelper());
+ if (!renderHelper->Init())
+ return nullptr;
+
+ static_cast<CAddonBase*>(CPrivateBase::m_interface->addonBase)->m_renderHelper =
+ renderHelper; // Hold on base for other types
+ return renderHelper;
+}
+
+} /* namespace gui */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/platform/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/platform/CMakeLists.txt
new file mode 100644
index 0000000..32a3910
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/platform/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_platform)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/CMakeLists.txt
new file mode 100644
index 0000000..7ea3672
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ $<$<STREQUAL:${CORE_SYSTEM_NAME},android>:System.h>
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_platform_android)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/System.h b/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/System.h
new file mode 100644
index 0000000..b7eb32c
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/System.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+/*---AUTO_GEN_PARSE<$$CORE_SYSTEM_NAME:android>---*/
+
+#pragma once
+
+#include "../../AddonBase.h"
+#include "../../c-api/platform/android/system.h"
+
+#ifdef __cplusplus
+namespace kodi
+{
+namespace platform
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_platform_CInterfaceAndroidSystem class CInterfaceAndroidSystem
+/// @ingroup cpp_kodi_platform
+/// @brief **Android platform specific functions**\n
+/// C++ class to query Android specific things in Kodi.
+///
+/// It has the header is @ref System.h "#include <kodi/platform/android/System.h>".
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/platform/android/System.h>
+///
+/// #if defined(ANDROID)
+/// kodi::platform::CInterfaceAndroidSystem system;
+/// if (system.GetSDKVersion() >= 23)
+/// {
+/// ...
+/// }
+/// #endif
+/// ~~~~~~~~~~~~~
+///
+class ATTR_DLL_LOCAL CInterfaceAndroidSystem
+{
+public:
+ CInterfaceAndroidSystem()
+ : m_interface(static_cast<AddonToKodiFuncTable_android_system*>(kodi::addon::GetInterface(
+ INTERFACE_ANDROID_SYSTEM_NAME, INTERFACE_ANDROID_SYSTEM_VERSION)))
+ {
+ }
+
+ //============================================================================
+ /// @ingroup cpp_kodi_platform_CInterfaceAndroidSystem
+ /// @brief Request an JNI env pointer for the calling thread.
+ ///
+ /// JNI env has to be controlled by kodi because of the underlying
+ /// threading concep.
+ ///
+ /// @return JNI env pointer for the calling thread
+ ///
+ inline void* GetJNIEnv()
+ {
+ if (m_interface)
+ return m_interface->get_jni_env();
+
+ return nullptr;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_platform_CInterfaceAndroidSystem
+ /// @brief Request the android sdk version to e.g. initialize <b>`JNIBase`</b>.
+ ///
+ /// @return Android SDK version
+ ///
+ inline int GetSDKVersion()
+ {
+ if (m_interface)
+ return m_interface->get_sdk_version();
+
+ return 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_platform_CInterfaceAndroidSystem
+ /// @brief Request the android main class name e.g. <b>`org.xbmc.kodi`</b>.
+ ///
+ /// @return package class name
+ ///
+ inline std::string GetClassName()
+ {
+ if (m_interface)
+ return m_interface->get_class_name();
+
+ return std::string();
+ }
+ //----------------------------------------------------------------------------
+
+private:
+ AddonToKodiFuncTable_android_system* m_interface;
+};
+//------------------------------------------------------------------------------
+
+} /* namespace platform */
+} /* namespace kodi */
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/tools/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/tools/CMakeLists.txt
new file mode 100644
index 0000000..d81acab
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/tools/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Auto generated CMakeLists.txt.
+# See xbmc/addons/kodi-dev-kit/tools/code-generator.py.
+
+set(HEADERS
+ DllHelper.h
+ EndTime.h
+ StringUtils.h
+ Thread.h
+ Timer.h
+)
+
+if(HEADERS)
+ core_add_devkit_header(kodi_tools)
+endif()
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h b/xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h
new file mode 100644
index 0000000..2003171
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+#include <string>
+
+#include <dlfcn.h>
+#include <kodi/AddonBase.h>
+#include <kodi/Filesystem.h>
+
+//==============================================================================
+/// @ingroup cpp_kodi_tools_CDllHelper
+/// @brief Macro to translate the given pointer value name of functions to
+/// requested function name.
+///
+/// @note This should always be used and does the work of
+/// @ref kodi::tools::CDllHelper::RegisterSymbol().
+///
+#define REGISTER_DLL_SYMBOL(functionPtr) \
+ kodi::tools::CDllHelper::RegisterSymbol(functionPtr, #functionPtr)
+//------------------------------------------------------------------------------
+
+namespace kodi
+{
+namespace tools
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_tools_CDllHelper class CDllHelper
+/// @ingroup cpp_kodi_tools
+/// @brief **Class to help with load of shared library functions**\n
+/// You can add them as parent to your class and to help with load of shared
+/// library functions.
+///
+/// @note To use on Windows must you also include [dlfcn-win32](https://github.com/dlfcn-win32/dlfcn-win32)
+/// on your addon!\n\n
+/// Furthermore, this allows the use of Android where the required library is
+/// copied to an EXE useable folder.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+///
+/// #include <kodi/tools/DllHelper.h>
+///
+/// ...
+/// class CMyInstance : public kodi::addon::CInstanceAudioDecoder,
+/// private kodi::tools::CDllHelper
+/// {
+/// public:
+/// CMyInstance(KODI_HANDLE instance, const std::string& kodiVersion);
+/// bool Start();
+///
+/// ...
+///
+/// // The pointers for on shared library exported functions
+/// int (*Init)();
+/// void (*Cleanup)();
+/// int (*GetLength)();
+/// };
+///
+/// CMyInstance::CMyInstance(KODI_HANDLE instance, const std::string& kodiVersion)
+/// : CInstanceAudioDecoder(instance, kodiVersion)
+/// {
+/// }
+///
+/// bool CMyInstance::Start()
+/// {
+/// std::string lib = kodi::GetAddonPath("myLib.so");
+/// if (!LoadDll(lib)) return false;
+/// if (!REGISTER_DLL_SYMBOL(Init)) return false;
+/// if (!REGISTER_DLL_SYMBOL(Cleanup)) return false;
+/// if (!REGISTER_DLL_SYMBOL(GetLength)) return false;
+///
+/// Init();
+/// return true;
+/// }
+/// ...
+/// ~~~~~~~~~~~~~
+///
+///@{
+class ATTR_DLL_LOCAL CDllHelper
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CDllHelper
+ /// @brief Class constructor.
+ ///
+ CDllHelper() = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CDllHelper
+ /// @brief Class destructor.
+ ///
+ virtual ~CDllHelper()
+ {
+ if (m_dll)
+ dlclose(m_dll);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CDllHelper
+ /// @brief Function to load requested library.
+ ///
+ /// @param[in] path The path with filename of shared library to load
+ /// @return true if load was successful done
+ ///
+ bool LoadDll(std::string path)
+ {
+#if defined(TARGET_ANDROID)
+ if (kodi::vfs::FileExists(path))
+ {
+ // Check already defined for "xbmcaltbinaddons", if yes no copy necassary.
+ std::string xbmcaltbinaddons =
+ kodi::vfs::TranslateSpecialProtocol("special://xbmcaltbinaddons/");
+ if (path.compare(0, xbmcaltbinaddons.length(), xbmcaltbinaddons) != 0)
+ {
+ bool doCopy = true;
+ std::string dstfile = xbmcaltbinaddons + kodi::vfs::GetFileName(path);
+
+ kodi::vfs::FileStatus dstFileStat;
+ if (kodi::vfs::StatFile(dstfile, dstFileStat))
+ {
+ kodi::vfs::FileStatus srcFileStat;
+ if (kodi::vfs::StatFile(path, srcFileStat))
+ {
+ if (dstFileStat.GetSize() == srcFileStat.GetSize() &&
+ dstFileStat.GetModificationTime() > srcFileStat.GetModificationTime())
+ doCopy = false;
+ }
+ }
+
+ if (doCopy)
+ {
+ kodi::Log(ADDON_LOG_DEBUG, "Caching '%s' to '%s'", path.c_str(), dstfile.c_str());
+ if (!kodi::vfs::CopyFile(path, dstfile))
+ {
+ kodi::Log(ADDON_LOG_ERROR, "Failed to cache '%s' to '%s'", path.c_str(),
+ dstfile.c_str());
+ return false;
+ }
+ }
+
+ path = dstfile;
+ }
+ }
+ else
+ {
+ return false;
+ }
+#endif
+
+ m_dll = dlopen(path.c_str(), RTLD_LOCAL | RTLD_LAZY);
+ if (m_dll == nullptr)
+ {
+ kodi::Log(ADDON_LOG_ERROR, "Unable to load %s", dlerror());
+ return false;
+ }
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CDllHelper
+ /// @brief Function to register requested library symbol.
+ ///
+ /// @warning This function should not be used, use instead the macro
+ /// @ref REGISTER_DLL_SYMBOL to register the symbol pointer.
+ ///
+ ///
+ /// Use this always via Macro, e.g.:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// if (!REGISTER_DLL_SYMBOL(Init))
+ /// return false;
+ /// ~~~~~~~~~~~~~
+ ///
+ template <typename T>
+ bool RegisterSymbol(T& functionPtr, const char* strFunctionPtr)
+ {
+ functionPtr = reinterpret_cast<T>(dlsym(m_dll, strFunctionPtr));
+ if (functionPtr == nullptr)
+ {
+ kodi::Log(ADDON_LOG_ERROR, "Unable to assign function %s", dlerror());
+ return false;
+ }
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+private:
+ void* m_dll = nullptr;
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace tools */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/tools/EndTime.h b/xbmc/addons/kodi-dev-kit/include/kodi/tools/EndTime.h
new file mode 100644
index 0000000..729bf2b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/tools/EndTime.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ * https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSE.md for more information.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+#include <chrono>
+
+namespace kodi
+{
+namespace tools
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_tools_CEndTime class CEndTime
+/// @ingroup cpp_kodi_tools
+/// @brief **Timeout check**\n
+/// Class which makes it easy to check if a specified amount of time has passed.
+///
+/// This code uses the support of platform-independent chrono system introduced
+/// with C++11.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/tools/EndTime.h>
+///
+/// class ATTR_DLL_LOCAL CExample
+/// {
+/// public:
+/// CExample()
+/// {
+/// TimerCall();
+/// }
+///
+/// void TimerCall()
+/// {
+/// fprintf(stderr, "Hello World\n");
+/// CEndTime timer(1000);
+///
+/// while (timer.MillisLeft())
+/// {
+/// if (timer.IsTimePast())
+/// {
+/// fprintf(stderr, "We timed out!\n");
+/// }
+/// std::this_thread::sleep_for(std::chrono::milliseconds(10));
+/// }
+/// }
+///
+/// };
+/// ~~~~~~~~~~~~~
+///
+///@{
+class CEndTime
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Class constructor with no time to expiry set
+ ///
+ inline CEndTime() = default;
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Class constructor to set future time when timer has expired
+ ///
+ /// @param[in] millisecondsIntoTheFuture the time in the future we cosider this timer as expired
+ ///
+ inline explicit CEndTime(unsigned int millisecondsIntoTheFuture)
+ : m_startTime(std::chrono::system_clock::now().time_since_epoch()),
+ m_totalWaitTime(std::chrono::milliseconds(millisecondsIntoTheFuture))
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Set the time in the future we cosider this timer as expired
+ ///
+ /// @param[in] millisecondsIntoTheFuture the time in the future we cosider this timer as expired
+ ///
+ inline void Set(unsigned int millisecondsIntoTheFuture)
+ {
+ using namespace std::chrono;
+
+ m_startTime = system_clock::now().time_since_epoch();
+ m_totalWaitTime = milliseconds(millisecondsIntoTheFuture);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Check if the expiry time has been reached
+ ///
+ /// @return True if the expiry amount of time has past, false otherwise
+ ///
+ inline bool IsTimePast() const
+ {
+ using namespace std::chrono;
+
+ // timer is infinite
+ if (m_totalWaitTime.count() == std::numeric_limits<unsigned int>::max())
+ return false;
+
+ if (m_totalWaitTime.count() == 0)
+ return true;
+ else
+ return (system_clock::now().time_since_epoch() - m_startTime) >= m_totalWaitTime;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief The amount of time left till this timer expires
+ ///
+ /// @return 0 if the expiry amount of time has past, the numbe rof milliseconds remaining otherwise
+ ///
+ inline unsigned int MillisLeft() const
+ {
+ using namespace std::chrono;
+
+ // timer is infinite
+ if (m_totalWaitTime.count() == std::numeric_limits<unsigned int>::max())
+ return std::numeric_limits<unsigned int>::max();
+
+ if (m_totalWaitTime.count() == 0)
+ return 0;
+
+ auto elapsed = system_clock::now().time_since_epoch() - m_startTime;
+
+ auto timeWaitedAlready = duration_cast<milliseconds>(elapsed).count();
+
+ if (timeWaitedAlready >= m_totalWaitTime.count())
+ return 0;
+
+ return static_cast<unsigned int>(m_totalWaitTime.count() - timeWaitedAlready);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Consider this timer expired
+ ///
+ inline void SetExpired()
+ {
+ using namespace std::chrono;
+ m_totalWaitTime = milliseconds(0);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Set this timer as never expiring
+ ///
+ inline void SetInfinite()
+ {
+ using namespace std::chrono;
+ m_totalWaitTime = milliseconds(std::numeric_limits<unsigned int>::max());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Check if the timer has been set to infinite expiry
+ ///
+ /// @return True if the expiry has been set as infinite, false otherwise
+ ///
+ inline bool IsInfinite(void) const
+ {
+ return (m_totalWaitTime.count() == std::numeric_limits<unsigned int>::max());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Get the initial timeout value this timer had
+ ///
+ /// @return The initial expiry amount of time this timer had in milliseconds
+ ///
+ inline unsigned int GetInitialTimeoutValue(void) const
+ {
+ auto value = std::chrono::duration_cast<std::chrono::milliseconds>(m_totalWaitTime);
+ return static_cast<unsigned int>(value.count());
+ }
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CEndTime
+ /// @brief Get the time this timer started
+ ///
+ /// @return The time this timer started in milliseconds since epoch
+ ///
+ inline uint64_t GetStartTime(void) const
+ {
+ auto value = std::chrono::duration_cast<std::chrono::milliseconds>(m_startTime);
+ return value.count();
+ }
+ //----------------------------------------------------------------------------
+
+private:
+ std::chrono::system_clock::duration m_startTime;
+ std::chrono::system_clock::duration m_totalWaitTime;
+};
+
+} /* namespace tools */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/tools/StringUtils.h b/xbmc/addons/kodi-dev-kit/include/kodi/tools/StringUtils.h
new file mode 100644
index 0000000..d1dede0
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/tools/StringUtils.h
@@ -0,0 +1,3086 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+#if !defined(NOMINMAX)
+#define NOMINMAX
+#endif
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <cinttypes>
+#include <cmath>
+#include <cstdarg>
+#include <cstring>
+#include <iomanip>
+#include <regex>
+#include <sstream>
+#include <string>
+#include <vector>
+
+// # of bytes for initial allocation for printf
+#define FORMAT_BLOCK_SIZE 512
+
+// macros for gcc, clang & others
+#ifndef PARAM1_PRINTF_FORMAT
+#ifdef __GNUC__
+// for use in functions that take printf format string as first parameter and additional printf parameters as second parameter
+// for example: int myprintf(const char* format, ...) PARAM1_PRINTF_FORMAT;
+#define PARAM1_PRINTF_FORMAT __attribute__((format(printf, 1, 2)))
+
+// for use in functions that take printf format string as second parameter and additional printf parameters as third parameter
+// for example: bool log_string(int logLevel, const char* format, ...) PARAM2_PRINTF_FORMAT;
+// note: all non-static class member functions take pointer to class object as hidden first parameter
+#define PARAM2_PRINTF_FORMAT __attribute__((format(printf, 2, 3)))
+
+// for use in functions that take printf format string as third parameter and additional printf parameters as fourth parameter
+// note: all non-static class member functions take pointer to class object as hidden first parameter
+// for example: class A { bool log_string(int logLevel, const char* functionName, const char* format, ...) PARAM3_PRINTF_FORMAT; };
+#define PARAM3_PRINTF_FORMAT __attribute__((format(printf, 3, 4)))
+
+// for use in functions that take printf format string as fourth parameter and additional printf parameters as fifth parameter
+// note: all non-static class member functions take pointer to class object as hidden first parameter
+// for example: class A { bool log_string(int logLevel, const char* functionName, int component, const char* format, ...) PARAM4_PRINTF_FORMAT; };
+#define PARAM4_PRINTF_FORMAT __attribute__((format(printf, 4, 5)))
+#else // ! __GNUC__
+#define PARAM1_PRINTF_FORMAT
+#define PARAM2_PRINTF_FORMAT
+#define PARAM3_PRINTF_FORMAT
+#define PARAM4_PRINTF_FORMAT
+#endif // ! __GNUC__
+#endif // PARAM1_PRINTF_FORMAT
+
+// macros for VC
+// VC check parameters only when "Code Analysis" is called
+#ifndef PRINTF_FORMAT_STRING
+#ifdef _MSC_VER
+#include <sal.h>
+
+// for use in any function that take printf format string and parameters
+// for example: bool log_string(int logLevel, PRINTF_FORMAT_STRING const char* format, ...);
+#define PRINTF_FORMAT_STRING _In_z_ _Printf_format_string_
+
+// specify that parameter must be zero-terminated string
+// for example: void SetName(IN_STRING const char* newName);
+#define IN_STRING _In_z_
+
+// specify that parameter must be zero-terminated string or NULL
+// for example: bool SetAdditionalName(IN_OPT_STRING const char* addName);
+#define IN_OPT_STRING _In_opt_z_
+#else // ! _MSC_VER
+#define PRINTF_FORMAT_STRING
+#define IN_STRING
+#define IN_OPT_STRING
+#endif // ! _MSC_VER
+#endif // PRINTF_FORMAT_STRING
+
+static constexpr wchar_t unicode_lowers[] = {
+ (wchar_t)0x0061, (wchar_t)0x0062, (wchar_t)0x0063, (wchar_t)0x0064, (wchar_t)0x0065,
+ (wchar_t)0x0066, (wchar_t)0x0067, (wchar_t)0x0068, (wchar_t)0x0069, (wchar_t)0x006A,
+ (wchar_t)0x006B, (wchar_t)0x006C, (wchar_t)0x006D, (wchar_t)0x006E, (wchar_t)0x006F,
+ (wchar_t)0x0070, (wchar_t)0x0071, (wchar_t)0x0072, (wchar_t)0x0073, (wchar_t)0x0074,
+ (wchar_t)0x0075, (wchar_t)0x0076, (wchar_t)0x0077, (wchar_t)0x0078, (wchar_t)0x0079,
+ (wchar_t)0x007A, (wchar_t)0x00E0, (wchar_t)0x00E1, (wchar_t)0x00E2, (wchar_t)0x00E3,
+ (wchar_t)0x00E4, (wchar_t)0x00E5, (wchar_t)0x00E6, (wchar_t)0x00E7, (wchar_t)0x00E8,
+ (wchar_t)0x00E9, (wchar_t)0x00EA, (wchar_t)0x00EB, (wchar_t)0x00EC, (wchar_t)0x00ED,
+ (wchar_t)0x00EE, (wchar_t)0x00EF, (wchar_t)0x00F0, (wchar_t)0x00F1, (wchar_t)0x00F2,
+ (wchar_t)0x00F3, (wchar_t)0x00F4, (wchar_t)0x00F5, (wchar_t)0x00F6, (wchar_t)0x00F8,
+ (wchar_t)0x00F9, (wchar_t)0x00FA, (wchar_t)0x00FB, (wchar_t)0x00FC, (wchar_t)0x00FD,
+ (wchar_t)0x00FE, (wchar_t)0x00FF, (wchar_t)0x0101, (wchar_t)0x0103, (wchar_t)0x0105,
+ (wchar_t)0x0107, (wchar_t)0x0109, (wchar_t)0x010B, (wchar_t)0x010D, (wchar_t)0x010F,
+ (wchar_t)0x0111, (wchar_t)0x0113, (wchar_t)0x0115, (wchar_t)0x0117, (wchar_t)0x0119,
+ (wchar_t)0x011B, (wchar_t)0x011D, (wchar_t)0x011F, (wchar_t)0x0121, (wchar_t)0x0123,
+ (wchar_t)0x0125, (wchar_t)0x0127, (wchar_t)0x0129, (wchar_t)0x012B, (wchar_t)0x012D,
+ (wchar_t)0x012F, (wchar_t)0x0131, (wchar_t)0x0133, (wchar_t)0x0135, (wchar_t)0x0137,
+ (wchar_t)0x013A, (wchar_t)0x013C, (wchar_t)0x013E, (wchar_t)0x0140, (wchar_t)0x0142,
+ (wchar_t)0x0144, (wchar_t)0x0146, (wchar_t)0x0148, (wchar_t)0x014B, (wchar_t)0x014D,
+ (wchar_t)0x014F, (wchar_t)0x0151, (wchar_t)0x0153, (wchar_t)0x0155, (wchar_t)0x0157,
+ (wchar_t)0x0159, (wchar_t)0x015B, (wchar_t)0x015D, (wchar_t)0x015F, (wchar_t)0x0161,
+ (wchar_t)0x0163, (wchar_t)0x0165, (wchar_t)0x0167, (wchar_t)0x0169, (wchar_t)0x016B,
+ (wchar_t)0x016D, (wchar_t)0x016F, (wchar_t)0x0171, (wchar_t)0x0173, (wchar_t)0x0175,
+ (wchar_t)0x0177, (wchar_t)0x017A, (wchar_t)0x017C, (wchar_t)0x017E, (wchar_t)0x0183,
+ (wchar_t)0x0185, (wchar_t)0x0188, (wchar_t)0x018C, (wchar_t)0x0192, (wchar_t)0x0199,
+ (wchar_t)0x01A1, (wchar_t)0x01A3, (wchar_t)0x01A5, (wchar_t)0x01A8, (wchar_t)0x01AD,
+ (wchar_t)0x01B0, (wchar_t)0x01B4, (wchar_t)0x01B6, (wchar_t)0x01B9, (wchar_t)0x01BD,
+ (wchar_t)0x01C6, (wchar_t)0x01C9, (wchar_t)0x01CC, (wchar_t)0x01CE, (wchar_t)0x01D0,
+ (wchar_t)0x01D2, (wchar_t)0x01D4, (wchar_t)0x01D6, (wchar_t)0x01D8, (wchar_t)0x01DA,
+ (wchar_t)0x01DC, (wchar_t)0x01DF, (wchar_t)0x01E1, (wchar_t)0x01E3, (wchar_t)0x01E5,
+ (wchar_t)0x01E7, (wchar_t)0x01E9, (wchar_t)0x01EB, (wchar_t)0x01ED, (wchar_t)0x01EF,
+ (wchar_t)0x01F3, (wchar_t)0x01F5, (wchar_t)0x01FB, (wchar_t)0x01FD, (wchar_t)0x01FF,
+ (wchar_t)0x0201, (wchar_t)0x0203, (wchar_t)0x0205, (wchar_t)0x0207, (wchar_t)0x0209,
+ (wchar_t)0x020B, (wchar_t)0x020D, (wchar_t)0x020F, (wchar_t)0x0211, (wchar_t)0x0213,
+ (wchar_t)0x0215, (wchar_t)0x0217, (wchar_t)0x0253, (wchar_t)0x0254, (wchar_t)0x0257,
+ (wchar_t)0x0258, (wchar_t)0x0259, (wchar_t)0x025B, (wchar_t)0x0260, (wchar_t)0x0263,
+ (wchar_t)0x0268, (wchar_t)0x0269, (wchar_t)0x026F, (wchar_t)0x0272, (wchar_t)0x0275,
+ (wchar_t)0x0283, (wchar_t)0x0288, (wchar_t)0x028A, (wchar_t)0x028B, (wchar_t)0x0292,
+ (wchar_t)0x03AC, (wchar_t)0x03AD, (wchar_t)0x03AE, (wchar_t)0x03AF, (wchar_t)0x03B1,
+ (wchar_t)0x03B2, (wchar_t)0x03B3, (wchar_t)0x03B4, (wchar_t)0x03B5, (wchar_t)0x03B6,
+ (wchar_t)0x03B7, (wchar_t)0x03B8, (wchar_t)0x03B9, (wchar_t)0x03BA, (wchar_t)0x03BB,
+ (wchar_t)0x03BC, (wchar_t)0x03BD, (wchar_t)0x03BE, (wchar_t)0x03BF, (wchar_t)0x03C0,
+ (wchar_t)0x03C1, (wchar_t)0x03C3, (wchar_t)0x03C4, (wchar_t)0x03C5, (wchar_t)0x03C6,
+ (wchar_t)0x03C7, (wchar_t)0x03C8, (wchar_t)0x03C9, (wchar_t)0x03CA, (wchar_t)0x03CB,
+ (wchar_t)0x03CC, (wchar_t)0x03CD, (wchar_t)0x03CE, (wchar_t)0x03E3, (wchar_t)0x03E5,
+ (wchar_t)0x03E7, (wchar_t)0x03E9, (wchar_t)0x03EB, (wchar_t)0x03ED, (wchar_t)0x03EF,
+ (wchar_t)0x0430, (wchar_t)0x0431, (wchar_t)0x0432, (wchar_t)0x0433, (wchar_t)0x0434,
+ (wchar_t)0x0435, (wchar_t)0x0436, (wchar_t)0x0437, (wchar_t)0x0438, (wchar_t)0x0439,
+ (wchar_t)0x043A, (wchar_t)0x043B, (wchar_t)0x043C, (wchar_t)0x043D, (wchar_t)0x043E,
+ (wchar_t)0x043F, (wchar_t)0x0440, (wchar_t)0x0441, (wchar_t)0x0442, (wchar_t)0x0443,
+ (wchar_t)0x0444, (wchar_t)0x0445, (wchar_t)0x0446, (wchar_t)0x0447, (wchar_t)0x0448,
+ (wchar_t)0x0449, (wchar_t)0x044A, (wchar_t)0x044B, (wchar_t)0x044C, (wchar_t)0x044D,
+ (wchar_t)0x044E, (wchar_t)0x044F, (wchar_t)0x0451, (wchar_t)0x0452, (wchar_t)0x0453,
+ (wchar_t)0x0454, (wchar_t)0x0455, (wchar_t)0x0456, (wchar_t)0x0457, (wchar_t)0x0458,
+ (wchar_t)0x0459, (wchar_t)0x045A, (wchar_t)0x045B, (wchar_t)0x045C, (wchar_t)0x045E,
+ (wchar_t)0x045F, (wchar_t)0x0461, (wchar_t)0x0463, (wchar_t)0x0465, (wchar_t)0x0467,
+ (wchar_t)0x0469, (wchar_t)0x046B, (wchar_t)0x046D, (wchar_t)0x046F, (wchar_t)0x0471,
+ (wchar_t)0x0473, (wchar_t)0x0475, (wchar_t)0x0477, (wchar_t)0x0479, (wchar_t)0x047B,
+ (wchar_t)0x047D, (wchar_t)0x047F, (wchar_t)0x0481, (wchar_t)0x0491, (wchar_t)0x0493,
+ (wchar_t)0x0495, (wchar_t)0x0497, (wchar_t)0x0499, (wchar_t)0x049B, (wchar_t)0x049D,
+ (wchar_t)0x049F, (wchar_t)0x04A1, (wchar_t)0x04A3, (wchar_t)0x04A5, (wchar_t)0x04A7,
+ (wchar_t)0x04A9, (wchar_t)0x04AB, (wchar_t)0x04AD, (wchar_t)0x04AF, (wchar_t)0x04B1,
+ (wchar_t)0x04B3, (wchar_t)0x04B5, (wchar_t)0x04B7, (wchar_t)0x04B9, (wchar_t)0x04BB,
+ (wchar_t)0x04BD, (wchar_t)0x04BF, (wchar_t)0x04C2, (wchar_t)0x04C4, (wchar_t)0x04C8,
+ (wchar_t)0x04CC, (wchar_t)0x04D1, (wchar_t)0x04D3, (wchar_t)0x04D5, (wchar_t)0x04D7,
+ (wchar_t)0x04D9, (wchar_t)0x04DB, (wchar_t)0x04DD, (wchar_t)0x04DF, (wchar_t)0x04E1,
+ (wchar_t)0x04E3, (wchar_t)0x04E5, (wchar_t)0x04E7, (wchar_t)0x04E9, (wchar_t)0x04EB,
+ (wchar_t)0x04EF, (wchar_t)0x04F1, (wchar_t)0x04F3, (wchar_t)0x04F5, (wchar_t)0x04F9,
+ (wchar_t)0x0561, (wchar_t)0x0562, (wchar_t)0x0563, (wchar_t)0x0564, (wchar_t)0x0565,
+ (wchar_t)0x0566, (wchar_t)0x0567, (wchar_t)0x0568, (wchar_t)0x0569, (wchar_t)0x056A,
+ (wchar_t)0x056B, (wchar_t)0x056C, (wchar_t)0x056D, (wchar_t)0x056E, (wchar_t)0x056F,
+ (wchar_t)0x0570, (wchar_t)0x0571, (wchar_t)0x0572, (wchar_t)0x0573, (wchar_t)0x0574,
+ (wchar_t)0x0575, (wchar_t)0x0576, (wchar_t)0x0577, (wchar_t)0x0578, (wchar_t)0x0579,
+ (wchar_t)0x057A, (wchar_t)0x057B, (wchar_t)0x057C, (wchar_t)0x057D, (wchar_t)0x057E,
+ (wchar_t)0x057F, (wchar_t)0x0580, (wchar_t)0x0581, (wchar_t)0x0582, (wchar_t)0x0583,
+ (wchar_t)0x0584, (wchar_t)0x0585, (wchar_t)0x0586, (wchar_t)0x10D0, (wchar_t)0x10D1,
+ (wchar_t)0x10D2, (wchar_t)0x10D3, (wchar_t)0x10D4, (wchar_t)0x10D5, (wchar_t)0x10D6,
+ (wchar_t)0x10D7, (wchar_t)0x10D8, (wchar_t)0x10D9, (wchar_t)0x10DA, (wchar_t)0x10DB,
+ (wchar_t)0x10DC, (wchar_t)0x10DD, (wchar_t)0x10DE, (wchar_t)0x10DF, (wchar_t)0x10E0,
+ (wchar_t)0x10E1, (wchar_t)0x10E2, (wchar_t)0x10E3, (wchar_t)0x10E4, (wchar_t)0x10E5,
+ (wchar_t)0x10E6, (wchar_t)0x10E7, (wchar_t)0x10E8, (wchar_t)0x10E9, (wchar_t)0x10EA,
+ (wchar_t)0x10EB, (wchar_t)0x10EC, (wchar_t)0x10ED, (wchar_t)0x10EE, (wchar_t)0x10EF,
+ (wchar_t)0x10F0, (wchar_t)0x10F1, (wchar_t)0x10F2, (wchar_t)0x10F3, (wchar_t)0x10F4,
+ (wchar_t)0x10F5, (wchar_t)0x1E01, (wchar_t)0x1E03, (wchar_t)0x1E05, (wchar_t)0x1E07,
+ (wchar_t)0x1E09, (wchar_t)0x1E0B, (wchar_t)0x1E0D, (wchar_t)0x1E0F, (wchar_t)0x1E11,
+ (wchar_t)0x1E13, (wchar_t)0x1E15, (wchar_t)0x1E17, (wchar_t)0x1E19, (wchar_t)0x1E1B,
+ (wchar_t)0x1E1D, (wchar_t)0x1E1F, (wchar_t)0x1E21, (wchar_t)0x1E23, (wchar_t)0x1E25,
+ (wchar_t)0x1E27, (wchar_t)0x1E29, (wchar_t)0x1E2B, (wchar_t)0x1E2D, (wchar_t)0x1E2F,
+ (wchar_t)0x1E31, (wchar_t)0x1E33, (wchar_t)0x1E35, (wchar_t)0x1E37, (wchar_t)0x1E39,
+ (wchar_t)0x1E3B, (wchar_t)0x1E3D, (wchar_t)0x1E3F, (wchar_t)0x1E41, (wchar_t)0x1E43,
+ (wchar_t)0x1E45, (wchar_t)0x1E47, (wchar_t)0x1E49, (wchar_t)0x1E4B, (wchar_t)0x1E4D,
+ (wchar_t)0x1E4F, (wchar_t)0x1E51, (wchar_t)0x1E53, (wchar_t)0x1E55, (wchar_t)0x1E57,
+ (wchar_t)0x1E59, (wchar_t)0x1E5B, (wchar_t)0x1E5D, (wchar_t)0x1E5F, (wchar_t)0x1E61,
+ (wchar_t)0x1E63, (wchar_t)0x1E65, (wchar_t)0x1E67, (wchar_t)0x1E69, (wchar_t)0x1E6B,
+ (wchar_t)0x1E6D, (wchar_t)0x1E6F, (wchar_t)0x1E71, (wchar_t)0x1E73, (wchar_t)0x1E75,
+ (wchar_t)0x1E77, (wchar_t)0x1E79, (wchar_t)0x1E7B, (wchar_t)0x1E7D, (wchar_t)0x1E7F,
+ (wchar_t)0x1E81, (wchar_t)0x1E83, (wchar_t)0x1E85, (wchar_t)0x1E87, (wchar_t)0x1E89,
+ (wchar_t)0x1E8B, (wchar_t)0x1E8D, (wchar_t)0x1E8F, (wchar_t)0x1E91, (wchar_t)0x1E93,
+ (wchar_t)0x1E95, (wchar_t)0x1EA1, (wchar_t)0x1EA3, (wchar_t)0x1EA5, (wchar_t)0x1EA7,
+ (wchar_t)0x1EA9, (wchar_t)0x1EAB, (wchar_t)0x1EAD, (wchar_t)0x1EAF, (wchar_t)0x1EB1,
+ (wchar_t)0x1EB3, (wchar_t)0x1EB5, (wchar_t)0x1EB7, (wchar_t)0x1EB9, (wchar_t)0x1EBB,
+ (wchar_t)0x1EBD, (wchar_t)0x1EBF, (wchar_t)0x1EC1, (wchar_t)0x1EC3, (wchar_t)0x1EC5,
+ (wchar_t)0x1EC7, (wchar_t)0x1EC9, (wchar_t)0x1ECB, (wchar_t)0x1ECD, (wchar_t)0x1ECF,
+ (wchar_t)0x1ED1, (wchar_t)0x1ED3, (wchar_t)0x1ED5, (wchar_t)0x1ED7, (wchar_t)0x1ED9,
+ (wchar_t)0x1EDB, (wchar_t)0x1EDD, (wchar_t)0x1EDF, (wchar_t)0x1EE1, (wchar_t)0x1EE3,
+ (wchar_t)0x1EE5, (wchar_t)0x1EE7, (wchar_t)0x1EE9, (wchar_t)0x1EEB, (wchar_t)0x1EED,
+ (wchar_t)0x1EEF, (wchar_t)0x1EF1, (wchar_t)0x1EF3, (wchar_t)0x1EF5, (wchar_t)0x1EF7,
+ (wchar_t)0x1EF9, (wchar_t)0x1F00, (wchar_t)0x1F01, (wchar_t)0x1F02, (wchar_t)0x1F03,
+ (wchar_t)0x1F04, (wchar_t)0x1F05, (wchar_t)0x1F06, (wchar_t)0x1F07, (wchar_t)0x1F10,
+ (wchar_t)0x1F11, (wchar_t)0x1F12, (wchar_t)0x1F13, (wchar_t)0x1F14, (wchar_t)0x1F15,
+ (wchar_t)0x1F20, (wchar_t)0x1F21, (wchar_t)0x1F22, (wchar_t)0x1F23, (wchar_t)0x1F24,
+ (wchar_t)0x1F25, (wchar_t)0x1F26, (wchar_t)0x1F27, (wchar_t)0x1F30, (wchar_t)0x1F31,
+ (wchar_t)0x1F32, (wchar_t)0x1F33, (wchar_t)0x1F34, (wchar_t)0x1F35, (wchar_t)0x1F36,
+ (wchar_t)0x1F37, (wchar_t)0x1F40, (wchar_t)0x1F41, (wchar_t)0x1F42, (wchar_t)0x1F43,
+ (wchar_t)0x1F44, (wchar_t)0x1F45, (wchar_t)0x1F51, (wchar_t)0x1F53, (wchar_t)0x1F55,
+ (wchar_t)0x1F57, (wchar_t)0x1F60, (wchar_t)0x1F61, (wchar_t)0x1F62, (wchar_t)0x1F63,
+ (wchar_t)0x1F64, (wchar_t)0x1F65, (wchar_t)0x1F66, (wchar_t)0x1F67, (wchar_t)0x1F80,
+ (wchar_t)0x1F81, (wchar_t)0x1F82, (wchar_t)0x1F83, (wchar_t)0x1F84, (wchar_t)0x1F85,
+ (wchar_t)0x1F86, (wchar_t)0x1F87, (wchar_t)0x1F90, (wchar_t)0x1F91, (wchar_t)0x1F92,
+ (wchar_t)0x1F93, (wchar_t)0x1F94, (wchar_t)0x1F95, (wchar_t)0x1F96, (wchar_t)0x1F97,
+ (wchar_t)0x1FA0, (wchar_t)0x1FA1, (wchar_t)0x1FA2, (wchar_t)0x1FA3, (wchar_t)0x1FA4,
+ (wchar_t)0x1FA5, (wchar_t)0x1FA6, (wchar_t)0x1FA7, (wchar_t)0x1FB0, (wchar_t)0x1FB1,
+ (wchar_t)0x1FD0, (wchar_t)0x1FD1, (wchar_t)0x1FE0, (wchar_t)0x1FE1, (wchar_t)0x24D0,
+ (wchar_t)0x24D1, (wchar_t)0x24D2, (wchar_t)0x24D3, (wchar_t)0x24D4, (wchar_t)0x24D5,
+ (wchar_t)0x24D6, (wchar_t)0x24D7, (wchar_t)0x24D8, (wchar_t)0x24D9, (wchar_t)0x24DA,
+ (wchar_t)0x24DB, (wchar_t)0x24DC, (wchar_t)0x24DD, (wchar_t)0x24DE, (wchar_t)0x24DF,
+ (wchar_t)0x24E0, (wchar_t)0x24E1, (wchar_t)0x24E2, (wchar_t)0x24E3, (wchar_t)0x24E4,
+ (wchar_t)0x24E5, (wchar_t)0x24E6, (wchar_t)0x24E7, (wchar_t)0x24E8, (wchar_t)0x24E9,
+ (wchar_t)0xFF41, (wchar_t)0xFF42, (wchar_t)0xFF43, (wchar_t)0xFF44, (wchar_t)0xFF45,
+ (wchar_t)0xFF46, (wchar_t)0xFF47, (wchar_t)0xFF48, (wchar_t)0xFF49, (wchar_t)0xFF4A,
+ (wchar_t)0xFF4B, (wchar_t)0xFF4C, (wchar_t)0xFF4D, (wchar_t)0xFF4E, (wchar_t)0xFF4F,
+ (wchar_t)0xFF50, (wchar_t)0xFF51, (wchar_t)0xFF52, (wchar_t)0xFF53, (wchar_t)0xFF54,
+ (wchar_t)0xFF55, (wchar_t)0xFF56, (wchar_t)0xFF57, (wchar_t)0xFF58, (wchar_t)0xFF59,
+ (wchar_t)0xFF5A};
+
+static const wchar_t unicode_uppers[] = {
+ (wchar_t)0x0041, (wchar_t)0x0042, (wchar_t)0x0043, (wchar_t)0x0044, (wchar_t)0x0045,
+ (wchar_t)0x0046, (wchar_t)0x0047, (wchar_t)0x0048, (wchar_t)0x0049, (wchar_t)0x004A,
+ (wchar_t)0x004B, (wchar_t)0x004C, (wchar_t)0x004D, (wchar_t)0x004E, (wchar_t)0x004F,
+ (wchar_t)0x0050, (wchar_t)0x0051, (wchar_t)0x0052, (wchar_t)0x0053, (wchar_t)0x0054,
+ (wchar_t)0x0055, (wchar_t)0x0056, (wchar_t)0x0057, (wchar_t)0x0058, (wchar_t)0x0059,
+ (wchar_t)0x005A, (wchar_t)0x00C0, (wchar_t)0x00C1, (wchar_t)0x00C2, (wchar_t)0x00C3,
+ (wchar_t)0x00C4, (wchar_t)0x00C5, (wchar_t)0x00C6, (wchar_t)0x00C7, (wchar_t)0x00C8,
+ (wchar_t)0x00C9, (wchar_t)0x00CA, (wchar_t)0x00CB, (wchar_t)0x00CC, (wchar_t)0x00CD,
+ (wchar_t)0x00CE, (wchar_t)0x00CF, (wchar_t)0x00D0, (wchar_t)0x00D1, (wchar_t)0x00D2,
+ (wchar_t)0x00D3, (wchar_t)0x00D4, (wchar_t)0x00D5, (wchar_t)0x00D6, (wchar_t)0x00D8,
+ (wchar_t)0x00D9, (wchar_t)0x00DA, (wchar_t)0x00DB, (wchar_t)0x00DC, (wchar_t)0x00DD,
+ (wchar_t)0x00DE, (wchar_t)0x0178, (wchar_t)0x0100, (wchar_t)0x0102, (wchar_t)0x0104,
+ (wchar_t)0x0106, (wchar_t)0x0108, (wchar_t)0x010A, (wchar_t)0x010C, (wchar_t)0x010E,
+ (wchar_t)0x0110, (wchar_t)0x0112, (wchar_t)0x0114, (wchar_t)0x0116, (wchar_t)0x0118,
+ (wchar_t)0x011A, (wchar_t)0x011C, (wchar_t)0x011E, (wchar_t)0x0120, (wchar_t)0x0122,
+ (wchar_t)0x0124, (wchar_t)0x0126, (wchar_t)0x0128, (wchar_t)0x012A, (wchar_t)0x012C,
+ (wchar_t)0x012E, (wchar_t)0x0049, (wchar_t)0x0132, (wchar_t)0x0134, (wchar_t)0x0136,
+ (wchar_t)0x0139, (wchar_t)0x013B, (wchar_t)0x013D, (wchar_t)0x013F, (wchar_t)0x0141,
+ (wchar_t)0x0143, (wchar_t)0x0145, (wchar_t)0x0147, (wchar_t)0x014A, (wchar_t)0x014C,
+ (wchar_t)0x014E, (wchar_t)0x0150, (wchar_t)0x0152, (wchar_t)0x0154, (wchar_t)0x0156,
+ (wchar_t)0x0158, (wchar_t)0x015A, (wchar_t)0x015C, (wchar_t)0x015E, (wchar_t)0x0160,
+ (wchar_t)0x0162, (wchar_t)0x0164, (wchar_t)0x0166, (wchar_t)0x0168, (wchar_t)0x016A,
+ (wchar_t)0x016C, (wchar_t)0x016E, (wchar_t)0x0170, (wchar_t)0x0172, (wchar_t)0x0174,
+ (wchar_t)0x0176, (wchar_t)0x0179, (wchar_t)0x017B, (wchar_t)0x017D, (wchar_t)0x0182,
+ (wchar_t)0x0184, (wchar_t)0x0187, (wchar_t)0x018B, (wchar_t)0x0191, (wchar_t)0x0198,
+ (wchar_t)0x01A0, (wchar_t)0x01A2, (wchar_t)0x01A4, (wchar_t)0x01A7, (wchar_t)0x01AC,
+ (wchar_t)0x01AF, (wchar_t)0x01B3, (wchar_t)0x01B5, (wchar_t)0x01B8, (wchar_t)0x01BC,
+ (wchar_t)0x01C4, (wchar_t)0x01C7, (wchar_t)0x01CA, (wchar_t)0x01CD, (wchar_t)0x01CF,
+ (wchar_t)0x01D1, (wchar_t)0x01D3, (wchar_t)0x01D5, (wchar_t)0x01D7, (wchar_t)0x01D9,
+ (wchar_t)0x01DB, (wchar_t)0x01DE, (wchar_t)0x01E0, (wchar_t)0x01E2, (wchar_t)0x01E4,
+ (wchar_t)0x01E6, (wchar_t)0x01E8, (wchar_t)0x01EA, (wchar_t)0x01EC, (wchar_t)0x01EE,
+ (wchar_t)0x01F1, (wchar_t)0x01F4, (wchar_t)0x01FA, (wchar_t)0x01FC, (wchar_t)0x01FE,
+ (wchar_t)0x0200, (wchar_t)0x0202, (wchar_t)0x0204, (wchar_t)0x0206, (wchar_t)0x0208,
+ (wchar_t)0x020A, (wchar_t)0x020C, (wchar_t)0x020E, (wchar_t)0x0210, (wchar_t)0x0212,
+ (wchar_t)0x0214, (wchar_t)0x0216, (wchar_t)0x0181, (wchar_t)0x0186, (wchar_t)0x018A,
+ (wchar_t)0x018E, (wchar_t)0x018F, (wchar_t)0x0190, (wchar_t)0x0193, (wchar_t)0x0194,
+ (wchar_t)0x0197, (wchar_t)0x0196, (wchar_t)0x019C, (wchar_t)0x019D, (wchar_t)0x019F,
+ (wchar_t)0x01A9, (wchar_t)0x01AE, (wchar_t)0x01B1, (wchar_t)0x01B2, (wchar_t)0x01B7,
+ (wchar_t)0x0386, (wchar_t)0x0388, (wchar_t)0x0389, (wchar_t)0x038A, (wchar_t)0x0391,
+ (wchar_t)0x0392, (wchar_t)0x0393, (wchar_t)0x0394, (wchar_t)0x0395, (wchar_t)0x0396,
+ (wchar_t)0x0397, (wchar_t)0x0398, (wchar_t)0x0399, (wchar_t)0x039A, (wchar_t)0x039B,
+ (wchar_t)0x039C, (wchar_t)0x039D, (wchar_t)0x039E, (wchar_t)0x039F, (wchar_t)0x03A0,
+ (wchar_t)0x03A1, (wchar_t)0x03A3, (wchar_t)0x03A4, (wchar_t)0x03A5, (wchar_t)0x03A6,
+ (wchar_t)0x03A7, (wchar_t)0x03A8, (wchar_t)0x03A9, (wchar_t)0x03AA, (wchar_t)0x03AB,
+ (wchar_t)0x038C, (wchar_t)0x038E, (wchar_t)0x038F, (wchar_t)0x03E2, (wchar_t)0x03E4,
+ (wchar_t)0x03E6, (wchar_t)0x03E8, (wchar_t)0x03EA, (wchar_t)0x03EC, (wchar_t)0x03EE,
+ (wchar_t)0x0410, (wchar_t)0x0411, (wchar_t)0x0412, (wchar_t)0x0413, (wchar_t)0x0414,
+ (wchar_t)0x0415, (wchar_t)0x0416, (wchar_t)0x0417, (wchar_t)0x0418, (wchar_t)0x0419,
+ (wchar_t)0x041A, (wchar_t)0x041B, (wchar_t)0x041C, (wchar_t)0x041D, (wchar_t)0x041E,
+ (wchar_t)0x041F, (wchar_t)0x0420, (wchar_t)0x0421, (wchar_t)0x0422, (wchar_t)0x0423,
+ (wchar_t)0x0424, (wchar_t)0x0425, (wchar_t)0x0426, (wchar_t)0x0427, (wchar_t)0x0428,
+ (wchar_t)0x0429, (wchar_t)0x042A, (wchar_t)0x042B, (wchar_t)0x042C, (wchar_t)0x042D,
+ (wchar_t)0x042E, (wchar_t)0x042F, (wchar_t)0x0401, (wchar_t)0x0402, (wchar_t)0x0403,
+ (wchar_t)0x0404, (wchar_t)0x0405, (wchar_t)0x0406, (wchar_t)0x0407, (wchar_t)0x0408,
+ (wchar_t)0x0409, (wchar_t)0x040A, (wchar_t)0x040B, (wchar_t)0x040C, (wchar_t)0x040E,
+ (wchar_t)0x040F, (wchar_t)0x0460, (wchar_t)0x0462, (wchar_t)0x0464, (wchar_t)0x0466,
+ (wchar_t)0x0468, (wchar_t)0x046A, (wchar_t)0x046C, (wchar_t)0x046E, (wchar_t)0x0470,
+ (wchar_t)0x0472, (wchar_t)0x0474, (wchar_t)0x0476, (wchar_t)0x0478, (wchar_t)0x047A,
+ (wchar_t)0x047C, (wchar_t)0x047E, (wchar_t)0x0480, (wchar_t)0x0490, (wchar_t)0x0492,
+ (wchar_t)0x0494, (wchar_t)0x0496, (wchar_t)0x0498, (wchar_t)0x049A, (wchar_t)0x049C,
+ (wchar_t)0x049E, (wchar_t)0x04A0, (wchar_t)0x04A2, (wchar_t)0x04A4, (wchar_t)0x04A6,
+ (wchar_t)0x04A8, (wchar_t)0x04AA, (wchar_t)0x04AC, (wchar_t)0x04AE, (wchar_t)0x04B0,
+ (wchar_t)0x04B2, (wchar_t)0x04B4, (wchar_t)0x04B6, (wchar_t)0x04B8, (wchar_t)0x04BA,
+ (wchar_t)0x04BC, (wchar_t)0x04BE, (wchar_t)0x04C1, (wchar_t)0x04C3, (wchar_t)0x04C7,
+ (wchar_t)0x04CB, (wchar_t)0x04D0, (wchar_t)0x04D2, (wchar_t)0x04D4, (wchar_t)0x04D6,
+ (wchar_t)0x04D8, (wchar_t)0x04DA, (wchar_t)0x04DC, (wchar_t)0x04DE, (wchar_t)0x04E0,
+ (wchar_t)0x04E2, (wchar_t)0x04E4, (wchar_t)0x04E6, (wchar_t)0x04E8, (wchar_t)0x04EA,
+ (wchar_t)0x04EE, (wchar_t)0x04F0, (wchar_t)0x04F2, (wchar_t)0x04F4, (wchar_t)0x04F8,
+ (wchar_t)0x0531, (wchar_t)0x0532, (wchar_t)0x0533, (wchar_t)0x0534, (wchar_t)0x0535,
+ (wchar_t)0x0536, (wchar_t)0x0537, (wchar_t)0x0538, (wchar_t)0x0539, (wchar_t)0x053A,
+ (wchar_t)0x053B, (wchar_t)0x053C, (wchar_t)0x053D, (wchar_t)0x053E, (wchar_t)0x053F,
+ (wchar_t)0x0540, (wchar_t)0x0541, (wchar_t)0x0542, (wchar_t)0x0543, (wchar_t)0x0544,
+ (wchar_t)0x0545, (wchar_t)0x0546, (wchar_t)0x0547, (wchar_t)0x0548, (wchar_t)0x0549,
+ (wchar_t)0x054A, (wchar_t)0x054B, (wchar_t)0x054C, (wchar_t)0x054D, (wchar_t)0x054E,
+ (wchar_t)0x054F, (wchar_t)0x0550, (wchar_t)0x0551, (wchar_t)0x0552, (wchar_t)0x0553,
+ (wchar_t)0x0554, (wchar_t)0x0555, (wchar_t)0x0556, (wchar_t)0x10A0, (wchar_t)0x10A1,
+ (wchar_t)0x10A2, (wchar_t)0x10A3, (wchar_t)0x10A4, (wchar_t)0x10A5, (wchar_t)0x10A6,
+ (wchar_t)0x10A7, (wchar_t)0x10A8, (wchar_t)0x10A9, (wchar_t)0x10AA, (wchar_t)0x10AB,
+ (wchar_t)0x10AC, (wchar_t)0x10AD, (wchar_t)0x10AE, (wchar_t)0x10AF, (wchar_t)0x10B0,
+ (wchar_t)0x10B1, (wchar_t)0x10B2, (wchar_t)0x10B3, (wchar_t)0x10B4, (wchar_t)0x10B5,
+ (wchar_t)0x10B6, (wchar_t)0x10B7, (wchar_t)0x10B8, (wchar_t)0x10B9, (wchar_t)0x10BA,
+ (wchar_t)0x10BB, (wchar_t)0x10BC, (wchar_t)0x10BD, (wchar_t)0x10BE, (wchar_t)0x10BF,
+ (wchar_t)0x10C0, (wchar_t)0x10C1, (wchar_t)0x10C2, (wchar_t)0x10C3, (wchar_t)0x10C4,
+ (wchar_t)0x10C5, (wchar_t)0x1E00, (wchar_t)0x1E02, (wchar_t)0x1E04, (wchar_t)0x1E06,
+ (wchar_t)0x1E08, (wchar_t)0x1E0A, (wchar_t)0x1E0C, (wchar_t)0x1E0E, (wchar_t)0x1E10,
+ (wchar_t)0x1E12, (wchar_t)0x1E14, (wchar_t)0x1E16, (wchar_t)0x1E18, (wchar_t)0x1E1A,
+ (wchar_t)0x1E1C, (wchar_t)0x1E1E, (wchar_t)0x1E20, (wchar_t)0x1E22, (wchar_t)0x1E24,
+ (wchar_t)0x1E26, (wchar_t)0x1E28, (wchar_t)0x1E2A, (wchar_t)0x1E2C, (wchar_t)0x1E2E,
+ (wchar_t)0x1E30, (wchar_t)0x1E32, (wchar_t)0x1E34, (wchar_t)0x1E36, (wchar_t)0x1E38,
+ (wchar_t)0x1E3A, (wchar_t)0x1E3C, (wchar_t)0x1E3E, (wchar_t)0x1E40, (wchar_t)0x1E42,
+ (wchar_t)0x1E44, (wchar_t)0x1E46, (wchar_t)0x1E48, (wchar_t)0x1E4A, (wchar_t)0x1E4C,
+ (wchar_t)0x1E4E, (wchar_t)0x1E50, (wchar_t)0x1E52, (wchar_t)0x1E54, (wchar_t)0x1E56,
+ (wchar_t)0x1E58, (wchar_t)0x1E5A, (wchar_t)0x1E5C, (wchar_t)0x1E5E, (wchar_t)0x1E60,
+ (wchar_t)0x1E62, (wchar_t)0x1E64, (wchar_t)0x1E66, (wchar_t)0x1E68, (wchar_t)0x1E6A,
+ (wchar_t)0x1E6C, (wchar_t)0x1E6E, (wchar_t)0x1E70, (wchar_t)0x1E72, (wchar_t)0x1E74,
+ (wchar_t)0x1E76, (wchar_t)0x1E78, (wchar_t)0x1E7A, (wchar_t)0x1E7C, (wchar_t)0x1E7E,
+ (wchar_t)0x1E80, (wchar_t)0x1E82, (wchar_t)0x1E84, (wchar_t)0x1E86, (wchar_t)0x1E88,
+ (wchar_t)0x1E8A, (wchar_t)0x1E8C, (wchar_t)0x1E8E, (wchar_t)0x1E90, (wchar_t)0x1E92,
+ (wchar_t)0x1E94, (wchar_t)0x1EA0, (wchar_t)0x1EA2, (wchar_t)0x1EA4, (wchar_t)0x1EA6,
+ (wchar_t)0x1EA8, (wchar_t)0x1EAA, (wchar_t)0x1EAC, (wchar_t)0x1EAE, (wchar_t)0x1EB0,
+ (wchar_t)0x1EB2, (wchar_t)0x1EB4, (wchar_t)0x1EB6, (wchar_t)0x1EB8, (wchar_t)0x1EBA,
+ (wchar_t)0x1EBC, (wchar_t)0x1EBE, (wchar_t)0x1EC0, (wchar_t)0x1EC2, (wchar_t)0x1EC4,
+ (wchar_t)0x1EC6, (wchar_t)0x1EC8, (wchar_t)0x1ECA, (wchar_t)0x1ECC, (wchar_t)0x1ECE,
+ (wchar_t)0x1ED0, (wchar_t)0x1ED2, (wchar_t)0x1ED4, (wchar_t)0x1ED6, (wchar_t)0x1ED8,
+ (wchar_t)0x1EDA, (wchar_t)0x1EDC, (wchar_t)0x1EDE, (wchar_t)0x1EE0, (wchar_t)0x1EE2,
+ (wchar_t)0x1EE4, (wchar_t)0x1EE6, (wchar_t)0x1EE8, (wchar_t)0x1EEA, (wchar_t)0x1EEC,
+ (wchar_t)0x1EEE, (wchar_t)0x1EF0, (wchar_t)0x1EF2, (wchar_t)0x1EF4, (wchar_t)0x1EF6,
+ (wchar_t)0x1EF8, (wchar_t)0x1F08, (wchar_t)0x1F09, (wchar_t)0x1F0A, (wchar_t)0x1F0B,
+ (wchar_t)0x1F0C, (wchar_t)0x1F0D, (wchar_t)0x1F0E, (wchar_t)0x1F0F, (wchar_t)0x1F18,
+ (wchar_t)0x1F19, (wchar_t)0x1F1A, (wchar_t)0x1F1B, (wchar_t)0x1F1C, (wchar_t)0x1F1D,
+ (wchar_t)0x1F28, (wchar_t)0x1F29, (wchar_t)0x1F2A, (wchar_t)0x1F2B, (wchar_t)0x1F2C,
+ (wchar_t)0x1F2D, (wchar_t)0x1F2E, (wchar_t)0x1F2F, (wchar_t)0x1F38, (wchar_t)0x1F39,
+ (wchar_t)0x1F3A, (wchar_t)0x1F3B, (wchar_t)0x1F3C, (wchar_t)0x1F3D, (wchar_t)0x1F3E,
+ (wchar_t)0x1F3F, (wchar_t)0x1F48, (wchar_t)0x1F49, (wchar_t)0x1F4A, (wchar_t)0x1F4B,
+ (wchar_t)0x1F4C, (wchar_t)0x1F4D, (wchar_t)0x1F59, (wchar_t)0x1F5B, (wchar_t)0x1F5D,
+ (wchar_t)0x1F5F, (wchar_t)0x1F68, (wchar_t)0x1F69, (wchar_t)0x1F6A, (wchar_t)0x1F6B,
+ (wchar_t)0x1F6C, (wchar_t)0x1F6D, (wchar_t)0x1F6E, (wchar_t)0x1F6F, (wchar_t)0x1F88,
+ (wchar_t)0x1F89, (wchar_t)0x1F8A, (wchar_t)0x1F8B, (wchar_t)0x1F8C, (wchar_t)0x1F8D,
+ (wchar_t)0x1F8E, (wchar_t)0x1F8F, (wchar_t)0x1F98, (wchar_t)0x1F99, (wchar_t)0x1F9A,
+ (wchar_t)0x1F9B, (wchar_t)0x1F9C, (wchar_t)0x1F9D, (wchar_t)0x1F9E, (wchar_t)0x1F9F,
+ (wchar_t)0x1FA8, (wchar_t)0x1FA9, (wchar_t)0x1FAA, (wchar_t)0x1FAB, (wchar_t)0x1FAC,
+ (wchar_t)0x1FAD, (wchar_t)0x1FAE, (wchar_t)0x1FAF, (wchar_t)0x1FB8, (wchar_t)0x1FB9,
+ (wchar_t)0x1FD8, (wchar_t)0x1FD9, (wchar_t)0x1FE8, (wchar_t)0x1FE9, (wchar_t)0x24B6,
+ (wchar_t)0x24B7, (wchar_t)0x24B8, (wchar_t)0x24B9, (wchar_t)0x24BA, (wchar_t)0x24BB,
+ (wchar_t)0x24BC, (wchar_t)0x24BD, (wchar_t)0x24BE, (wchar_t)0x24BF, (wchar_t)0x24C0,
+ (wchar_t)0x24C1, (wchar_t)0x24C2, (wchar_t)0x24C3, (wchar_t)0x24C4, (wchar_t)0x24C5,
+ (wchar_t)0x24C6, (wchar_t)0x24C7, (wchar_t)0x24C8, (wchar_t)0x24C9, (wchar_t)0x24CA,
+ (wchar_t)0x24CB, (wchar_t)0x24CC, (wchar_t)0x24CD, (wchar_t)0x24CE, (wchar_t)0x24CF,
+ (wchar_t)0xFF21, (wchar_t)0xFF22, (wchar_t)0xFF23, (wchar_t)0xFF24, (wchar_t)0xFF25,
+ (wchar_t)0xFF26, (wchar_t)0xFF27, (wchar_t)0xFF28, (wchar_t)0xFF29, (wchar_t)0xFF2A,
+ (wchar_t)0xFF2B, (wchar_t)0xFF2C, (wchar_t)0xFF2D, (wchar_t)0xFF2E, (wchar_t)0xFF2F,
+ (wchar_t)0xFF30, (wchar_t)0xFF31, (wchar_t)0xFF32, (wchar_t)0xFF33, (wchar_t)0xFF34,
+ (wchar_t)0xFF35, (wchar_t)0xFF36, (wchar_t)0xFF37, (wchar_t)0xFF38, (wchar_t)0xFF39,
+ (wchar_t)0xFF3A};
+
+namespace kodi
+{
+namespace tools
+{
+
+template<typename T, std::enable_if_t<!std::is_enum<T>::value, int> = 0>
+constexpr auto&& EnumToInt(T&& arg) noexcept
+{
+ return arg;
+}
+template<typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
+constexpr auto EnumToInt(T&& arg) noexcept
+{
+ return static_cast<int>(arg);
+}
+
+//==============================================================================
+/// @defgroup cpp_kodi_tools_StringUtils_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_tools_StringUtils
+/// @brief **Parts used within string util functions**\n
+/// All to string functions associated data structures.
+///
+/// It is divided into individual modules that correspond to the respective
+/// types.
+///
+///
+///
+
+//==============================================================================
+/// @defgroup cpp_kodi_tools_StringUtils_Defs_TIME_FORMAT enum TIME_FORMAT
+/// @ingroup cpp_kodi_tools_StringUtils_Defs
+/// @brief TIME_FORMAT enum/bitmask used for formatting time strings.
+///
+/// Note the use of bitmasking, e.g. TIME_FORMAT_HH_MM_SS = TIME_FORMAT_HH | TIME_FORMAT_MM | TIME_FORMAT_SS
+/// @sa kodi::tools::StringUtils::SecondsToTimeString
+///
+/// @note For InfoLabels use the equivalent value listed (bold) on the
+/// description of each enum value.
+///
+/// <b>Example:</b> 3661 seconds => h=1, hh=01, m=1, mm=01, ss=01, hours=1, mins=61, secs=3661
+///
+///@{
+enum TIME_FORMAT
+{
+ /// Usually used as the fallback value if the format value is empty
+ TIME_FORMAT_GUESS = 0,
+
+ /// <b>ss</b> - seconds only
+ TIME_FORMAT_SS = 1,
+
+ /// <b>mm</b> - minutes only (2-digit)
+ TIME_FORMAT_MM = 2,
+
+ /// <b>mm:ss</b> - minutes and seconds
+ TIME_FORMAT_MM_SS = 3,
+
+ /// <b>hh</b> - hours only (2-digit)
+ TIME_FORMAT_HH = 4,
+
+ /// <b>hh:ss</b> - hours and seconds (this is not particularly useful)
+ TIME_FORMAT_HH_SS = 5,
+
+ /// <b>hh:mm</b> - hours and minutes
+ TIME_FORMAT_HH_MM = 6,
+
+ /// <b>hh:mm:ss</b> - hours, minutes and seconds
+ TIME_FORMAT_HH_MM_SS = 7,
+
+ /// <b>xx</b> - returns AM/PM for a 12-hour clock
+ TIME_FORMAT_XX = 8,
+
+ /// <b>hh:mm xx</b> - returns hours and minutes in a 12-hour clock format (AM/PM)
+ TIME_FORMAT_HH_MM_XX = 14,
+
+ /// <b>hh:mm:ss xx</b> - returns hours (2-digit), minutes and seconds in a 12-hour clock format (AM/PM)
+ TIME_FORMAT_HH_MM_SS_XX = 15,
+
+ /// <b>h</b> - hours only (1-digit)
+ TIME_FORMAT_H = 16,
+
+ /// <b>hh:mm:ss</b> - hours, minutes and seconds
+ TIME_FORMAT_H_MM_SS = 19,
+
+ /// <b>hh:mm:ss xx</b> - returns hours (1-digit), minutes and seconds in a 12-hour clock format (AM/PM)
+ TIME_FORMAT_H_MM_SS_XX = 27,
+
+ /// <b>secs</b> - total time in seconds
+ TIME_FORMAT_SECS = 32,
+
+ /// <b>mins</b> - total time in minutes
+ TIME_FORMAT_MINS = 64,
+
+ /// <b>hours</b> - total time in hours
+ TIME_FORMAT_HOURS = 128,
+
+ /// <b>m</b> - minutes only (1-digit)
+ TIME_FORMAT_M = 256
+};
+///@}
+//------------------------------------------------------------------------------
+
+//==============================================================================
+/// @defgroup cpp_kodi_tools_StringUtils class StringUtils
+/// @ingroup cpp_kodi_tools
+/// @brief **C++ class for processing strings**\n
+/// This class brings many different functions to edit, check or search texts.
+///
+/// Is intended to reduce any code work of C++ on addons and to have them faster
+/// to use.
+///
+/// All functions are static within the <b>`kodi::tools::StringUtils`</b> class.
+///
+///@{
+class StringUtils
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_StringUtils_Defs
+ /// @brief Defines a static empty <b>`std::string`</b>.
+ ///
+ static const std::string Empty;
+ //----------------------------------------------------------------------------
+
+ //----------------------------------------------------------------------------
+ /// @defgroup cpp_kodi_tools_StringUtils_FormatControl String format
+ /// @ingroup cpp_kodi_tools_StringUtils
+ /// @brief **Formatting functions**\n
+ /// Used to output the given values in newly formatted text using functions.
+ ///
+ /*!@{*/
+
+ //============================================================================
+ /// @brief Returns the C++ string pointed by given format. If format includes
+ /// format specifiers (subsequences beginning with %), the additional arguments
+ /// following format are formatted and inserted in the resulting string replacing
+ /// their respective specifiers.
+ ///
+ /// After the format parameter, the function expects at least as many additional
+ /// arguments as specified by format.
+ ///
+ /// @param[in] fmt The format of the text to process for output.
+ /// C string that contains the text to be written to the stream.
+ /// It can optionally contain embedded format specifiers that are
+ /// replaced by the values specified in subsequent additional
+ /// arguments and formatted as requested.
+ /// | specifier | Output | Example
+ /// |------------|----------------------------------------------------|------------
+ /// | d or i | Signed decimal integer | 392
+ /// | u | Unsigned decimal integer | 7235
+ /// | o | Unsigned octal | 610
+ /// | x | Unsigned hexadecimal integer | 7fa
+ /// | X | Unsigned hexadecimal integer (uppercase) | 7FA
+ /// | f | Decimal floating point, lowercase | 392.65
+ /// | F | Decimal floating point, uppercase | 392.65
+ /// | e | Scientific notation (mantissa/exponent), lowercase | 3.9265e+2
+ /// | E | Scientific notation (mantissa/exponent), uppercase | 3.9265E+2
+ /// | g | Use the shortest representation: %e or %f | 392.65
+ /// | G | Use the shortest representation: %E or %F | 392.65
+ /// | a | Hexadecimal floating point, lowercase | -0xc.90fep-2
+ /// | A | Hexadecimal floating point, uppercase | -0XC.90FEP-2
+ /// | c | Character | a
+ /// | s | String of characters | sample
+ /// | p | Pointer address | b8000000
+ /// | % | A % followed by another % character will write a single % to the stream. | %
+ /// The length sub-specifier modifies the length of the data type. This is a chart
+ /// showing the types used to interpret the corresponding arguments with and without
+ /// length specifier (if a different type is used, the proper type promotion or
+ /// conversion is performed, if allowed):
+ /// | length| d i | u o x X | f F e E g G a A | c | s | p | n |
+ /// |-------|---------------|-----------------------|-----------------|-------|---------|---------|-----------------|
+ /// | (none)| int | unsigned int | double | int | char* | void* | int* |
+ /// | hh | signed char | unsigned char | | | | | signed char* |
+ /// | h | short int | unsigned short int | | | | | short int* |
+ /// | l | long int | unsigned long int | | wint_t| wchar_t*| | long int* |
+ /// | ll | long long int | unsigned long long int| | | | | long long int* |
+ /// | j | intmax_t | uintmax_t | | | | | intmax_t* |
+ /// | z | size_t | size_t | | | | | size_t* |
+ /// | t | ptrdiff_t | ptrdiff_t | | | | | ptrdiff_t* |
+ /// | L | | | long double | | | | |
+ /// <b>Note:</b> that the c specifier takes an int (or wint_t) as argument, but performs the proper conversion to a char value
+ /// (or a wchar_t) before formatting it for output.
+ /// @param[in] ... <i>(additional arguments)</i>\n
+ /// Depending on the format string, the function may expect a
+ /// sequence of additional arguments, each containing a value
+ /// to be used to replace a format specifier in the format
+ /// string (or a pointer to a storage location, for n).\n
+ /// There should be at least as many of these arguments as the
+ /// number of values specified in the format specifiers.
+ /// Additional arguments are ignored by the function.
+ /// @return Formatted string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string str = kodi::tools::StringUtils::Format("Hello {} {}", "World", 2020);
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string Format(const char* fmt, ...)
+ {
+ va_list args;
+ va_start(args, fmt);
+ std::string str = FormatV(fmt, args);
+ va_end(args);
+
+ return str;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Returns the C++ wide string pointed by given format.
+ ///
+ /// @param[in] fmt The format of the text to process for output
+ /// (see @ref Format(const char* fmt, ...) for details).
+ /// @param[in] ... <i>(additional arguments)</i>\n
+ /// Depending on the format string, the function may expect a
+ /// sequence of additional arguments, each containing a value
+ /// to be used to replace a format specifier in the format
+ /// string (or a pointer to a storage location, for n).\n
+ /// There should be at least as many of these arguments as the
+ /// number of values specified in the format specifiers.
+ /// Additional arguments are ignored by the function.
+ /// @return Formatted string
+ ///
+ inline static std::wstring Format(const wchar_t* fmt, ...)
+ {
+ va_list args;
+ va_start(args, fmt);
+ std::wstring str = FormatV(fmt, args);
+ va_end(args);
+
+ return str;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Returns the C++ string pointed by given format list.
+ ///
+ /// @param[in] fmt The format of the text to process for output
+ /// (see @ref Format(const char* fmt, ...) for details).
+ /// @param[in] args A value identifying a variable arguments list initialized
+ /// with `va_start`.
+ /// @return Formatted string
+ ///
+ inline static std::string FormatV(PRINTF_FORMAT_STRING const char* fmt, va_list args)
+ {
+ if (!fmt || !fmt[0])
+ return "";
+
+ int size = FORMAT_BLOCK_SIZE;
+ va_list argCopy;
+
+ while (true)
+ {
+ char* cstr = reinterpret_cast<char*>(malloc(sizeof(char) * size));
+ if (!cstr)
+ return "";
+
+ va_copy(argCopy, args);
+ int nActual = vsnprintf(cstr, size, fmt, argCopy);
+ va_end(argCopy);
+
+ if (nActual > -1 && nActual < size) // We got a valid result
+ {
+ std::string str(cstr, nActual);
+ free(cstr);
+ return str;
+ }
+ free(cstr);
+#ifndef TARGET_WINDOWS
+ if (nActual > -1) // Exactly what we will need (glibc 2.1)
+ size = nActual + 1;
+ else // Let's try to double the size (glibc 2.0)
+ size *= 2;
+#else // TARGET_WINDOWS
+ va_copy(argCopy, args);
+ size = _vscprintf(fmt, argCopy);
+ va_end(argCopy);
+ if (size < 0)
+ return "";
+ else
+ size++; // increment for null-termination
+#endif // TARGET_WINDOWS
+ }
+
+ return ""; // unreachable
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Returns the C++ wide string pointed by given format list.
+ ///
+ /// @param[in] fmt The format of the text to process for output
+ /// (see @ref Format(const char* fmt, ...) for details).
+ /// @param[in] args A value identifying a variable arguments list initialized
+ /// with `va_start`.
+ /// @return Formatted string
+ ///
+ inline static std::wstring FormatV(PRINTF_FORMAT_STRING const wchar_t* fmt, va_list args)
+ {
+ if (!fmt || !fmt[0])
+ return L"";
+
+ int size = FORMAT_BLOCK_SIZE;
+ va_list argCopy;
+
+ while (true)
+ {
+ wchar_t* cstr = reinterpret_cast<wchar_t*>(malloc(sizeof(wchar_t) * size));
+ if (!cstr)
+ return L"";
+
+ va_copy(argCopy, args);
+ int nActual = vswprintf(cstr, size, fmt, argCopy);
+ va_end(argCopy);
+
+ if (nActual > -1 && nActual < size) // We got a valid result
+ {
+ std::wstring str(cstr, nActual);
+ free(cstr);
+ return str;
+ }
+ free(cstr);
+
+#ifndef TARGET_WINDOWS
+ if (nActual > -1) // Exactly what we will need (glibc 2.1)
+ size = nActual + 1;
+ else // Let's try to double the size (glibc 2.0)
+ size *= 2;
+#else // TARGET_WINDOWS
+ va_copy(argCopy, args);
+ size = _vscwprintf(fmt, argCopy);
+ va_end(argCopy);
+ if (size < 0)
+ return L"";
+ else
+ size++; // increment for null-termination
+#endif // TARGET_WINDOWS
+ }
+
+ return L"";
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Returns bytes in a human readable format using the smallest unit
+ /// that will fit `bytes` in at most three digits. The number of decimals are
+ /// adjusted with significance such that 'small' numbers will have more
+ /// decimals than larger ones.
+ ///
+ /// For example: 1024 bytes will be formatted as "1.00kB", 10240 bytes as
+ /// "10.0kB" and 102400 bytes as "100kB". See TestStringUtils for more
+ /// examples.
+ ///
+ /// Supported file sizes:
+ /// | Value | Short | Metric
+ /// |------------|-------|-----------
+ /// | 1 | B | byte
+ /// | 1024¹ | kB | kilobyte
+ /// | 1024² | MB | megabyte
+ /// | 1024³ | GB | gigabyte
+ /// | 1024 exp 4 | TB | terabyte
+ /// | 1024 exp 5 | PB | petabyte
+ /// | 1024 exp 6 | EB | exabyte
+ /// | 1024 exp 7 | ZB | zettabyte
+ /// | 1024 exp 8 | YB | yottabyte
+ ///
+ /// @param[in] bytes Bytes amount to return as human readable string
+ /// @return Size as string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// EXPECT_STREQ("0B", kodi::tools::StringUtils::FormatFileSize(0).c_str());
+ ///
+ /// EXPECT_STREQ("999B", kodi::tools::StringUtils::FormatFileSize(999).c_str());
+ /// EXPECT_STREQ("0.98kB", kodi::tools::StringUtils::FormatFileSize(1000).c_str());
+ ///
+ /// EXPECT_STREQ("1.00kB", kodi::tools::StringUtils::FormatFileSize(1024).c_str());
+ /// EXPECT_STREQ("9.99kB", kodi::tools::StringUtils::FormatFileSize(10229).c_str());
+ ///
+ /// EXPECT_STREQ("10.1kB", kodi::tools::StringUtils::FormatFileSize(10387).c_str());
+ /// EXPECT_STREQ("99.9kB", kodi::tools::StringUtils::FormatFileSize(102297).c_str());
+ ///
+ /// EXPECT_STREQ("100kB", kodi::tools::StringUtils::FormatFileSize(102400).c_str());
+ /// EXPECT_STREQ("999kB", kodi::tools::StringUtils::FormatFileSize(1023431).c_str());
+ ///
+ /// EXPECT_STREQ("0.98MB", kodi::tools::StringUtils::FormatFileSize(1023897).c_str());
+ /// EXPECT_STREQ("0.98MB", kodi::tools::StringUtils::FormatFileSize(1024000).c_str());
+ ///
+ /// EXPECT_STREQ("5.30EB", kodi::tools::StringUtils::FormatFileSize(6115888293969133568).c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string FormatFileSize(uint64_t bytes)
+ {
+ const std::array<std::string, 9> units{{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}};
+ if (bytes < 1000)
+ return Format("%" PRIu64 "B", bytes);
+
+ size_t i = 0;
+ double value = static_cast<double>(bytes);
+ while (i + 1 < units.size() && value >= 999.5)
+ {
+ ++i;
+ value /= 1024.0;
+ }
+ unsigned int decimals = value < 9.995 ? 2 : (value < 99.95 ? 1 : 0);
+ auto frmt = "%." + Format("%u", decimals) + "f%s";
+ return Format(frmt.c_str(), value, units[i].c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Convert the string of binary chars to the actual string.
+ ///
+ /// Convert the string representation of binary chars to the actual string.
+ /// For example <b>`\1\2\3`</b> is converted to a string with binary char
+ /// <b>`\1`</b>, <b>`\2`</b> and <b>`\3`</b>
+ ///
+ /// @param[in] in String to convert
+ /// @return Converted string
+ ///
+ inline static std::string BinaryStringToString(const std::string& in)
+ {
+ std::string out;
+ out.reserve(in.size() / 2);
+ for (const char *cur = in.c_str(), *end = cur + in.size(); cur != end; ++cur)
+ {
+ if (*cur == '\\')
+ {
+ ++cur;
+ if (cur == end)
+ {
+ break;
+ }
+ if (isdigit(*cur))
+ {
+ char* end;
+ unsigned long num = strtol(cur, &end, 10);
+ cur = end - 1;
+ out.push_back(static_cast<char>(num));
+ continue;
+ }
+ }
+ out.push_back(*cur);
+ }
+ return out;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Convert each character in the string to its hexadecimal
+ /// representation and return the concatenated result
+ ///
+ /// Example: "abc\n" -> "6162630a"
+ ///
+ /// @param[in] in String to convert
+ /// @return Converted string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// EXPECT_STREQ("", kodi::tools::StringUtils::ToHexadecimal("").c_str());
+ /// EXPECT_STREQ("616263", kodi::tools::StringUtils::ToHexadecimal("abc").c_str());
+ /// std::string a{"a\0b\n", 4};
+ /// EXPECT_STREQ("6100620a", kodi::tools::StringUtils::ToHexadecimal(a).c_str());
+ /// std::string nul{"\0", 1};
+ /// EXPECT_STREQ("00", kodi::tools::StringUtils::ToHexadecimal(nul).c_str());
+ /// std::string ff{"\xFF", 1};
+ /// EXPECT_STREQ("ff", kodi::tools::StringUtils::ToHexadecimal(ff).c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string ToHexadecimal(const std::string& in)
+ {
+ std::ostringstream ss;
+ ss << std::hex;
+ for (unsigned char ch : in)
+ {
+ ss << std::setw(2) << std::setfill('0') << static_cast<unsigned long>(ch);
+ }
+ return ss.str();
+ }
+ //----------------------------------------------------------------------------
+
+ /*!@}*/
+
+ //----------------------------------------------------------------------------
+ /// @defgroup cpp_kodi_tools_StringUtils_EditControl String edit
+ /// @ingroup cpp_kodi_tools_StringUtils
+ /// @brief **Edits given texts**\n
+ /// This is used to revise the respective strings and to get them in the desired format.
+ ///
+ /*!@{*/
+
+ //============================================================================
+ /// @brief Convert a string to uppercase.
+ ///
+ /// @param[in,out] str String to convert
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = "TEST";
+ ///
+ /// std::string varstr = "TeSt";
+ /// kodi::tools::StringUtils::ToUpper(varstr);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static void ToUpper(std::string& str)
+ {
+ std::transform(str.begin(), str.end(), str.begin(), ::toupper);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Convert a 16bit wide string to uppercase.
+ ///
+ /// @param[in,out] str String to convert
+ ///
+ inline static void ToUpper(std::wstring& str)
+ {
+ transform(str.begin(), str.end(), str.begin(), toupperUnicode);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Convert a string to lowercase.
+ ///
+ /// @param[in,out] str String to convert
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = "test";
+ ///
+ /// std::string varstr = "TeSt";
+ /// kodi::tools::StringUtils::ToLower(varstr);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static void ToLower(std::string& str)
+ {
+ transform(str.begin(), str.end(), str.begin(), ::tolower);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Convert a 16bit wide string to lowercase.
+ ///
+ /// @param[in,out] str String to convert
+ ///
+ inline static void ToLower(std::wstring& str)
+ {
+ transform(str.begin(), str.end(), str.begin(), tolowerUnicode);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Combine all numerical digits and give it as integer value.
+ ///
+ /// @param[in,out] str String to check for digits
+ /// @return All numerical digits fit together as integer value
+ ///
+ inline static int ReturnDigits(const std::string& str)
+ {
+ std::stringstream ss;
+ for (const auto& character : str)
+ {
+ if (isdigit(character))
+ ss << character;
+ }
+ return atoi(ss.str().c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Returns a string from start with givent count.
+ ///
+ /// @param[in] str String to use
+ /// @param[in] count Amount of characters to go from left
+ /// @return The left part string in amount of given count or complete if it
+ /// was higher.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr, varstr;
+ /// std::string origstr = "test";
+ ///
+ /// refstr = "";
+ /// varstr = kodi::tools::StringUtils::Left(origstr, 0);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "te";
+ /// varstr = kodi::tools::StringUtils::Left(origstr, 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "test";
+ /// varstr = kodi::tools::StringUtils::Left(origstr, 10);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string Left(const std::string& str, size_t count)
+ {
+ count = std::max((size_t)0, std::min(count, str.size()));
+ return str.substr(0, count);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Get substring from mid of given string.
+ ///
+ /// @param[in] str String to get substring from
+ /// @param[in] first Position from where to start
+ /// @param[in] count [opt] length of position to get after start, default is
+ /// complete to end
+ /// @return The substring taken from middle of input string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr, varstr;
+ /// std::string origstr = "test";
+ ///
+ /// refstr = "";
+ /// varstr = kodi::tools::StringUtils::Mid(origstr, 0, 0);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "te";
+ /// varstr = kodi::tools::StringUtils::Mid(origstr, 0, 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "test";
+ /// varstr = kodi::tools::StringUtils::Mid(origstr, 0, 10);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "st";
+ /// varstr = kodi::tools::StringUtils::Mid(origstr, 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "st";
+ /// varstr = kodi::tools::StringUtils::Mid(origstr, 2, 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "es";
+ /// varstr = kodi::tools::StringUtils::Mid(origstr, 1, 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string Mid(const std::string& str,
+ size_t first,
+ size_t count = std::string::npos)
+ {
+ if (first + count > str.size())
+ count = str.size() - first;
+
+ if (first > str.size())
+ return std::string();
+
+ assert(first + count <= str.size());
+
+ return str.substr(first, count);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Returns a string from end with givent count.
+ ///
+ /// @param[in] str String to use
+ /// @param[in] count Amount of characters to go from right
+ /// @return The right part string in amount of given count or complete if it
+ /// was higher.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr, varstr;
+ /// std::string origstr = "test";
+ ///
+ /// refstr = "";
+ /// varstr = kodi::tools::StringUtils::Right(origstr, 0);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "st";
+ /// varstr = kodi::tools::StringUtils::Right(origstr, 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// refstr = "test";
+ /// varstr = kodi::tools::StringUtils::Right(origstr, 10);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string Right(const std::string& str, size_t count)
+ {
+ count = std::max((size_t)0, std::min(count, str.size()));
+ return str.substr(str.size() - count);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Trim a string with remove of not wanted spaces at begin and end
+ /// of string.
+ ///
+ /// @param[in,out] str String to trim, becomes also changed and given on
+ /// return
+ /// @return The changed string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = "test test";
+ ///
+ /// std::string varstr = " test test ";
+ /// kodi::tools::StringUtils::Trim(varstr);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string& Trim(std::string& str)
+ {
+ TrimLeft(str);
+ return TrimRight(str);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Trim a string with remove of not wanted characters at begin and end
+ /// of string.
+ ///
+ /// @param[in,out] str String to trim, becomes also changed and given on
+ /// return
+ /// @param[in] chars Characters to use for trim
+ /// @return The changed string
+ ///
+ inline static std::string& Trim(std::string& str, const char* const chars)
+ {
+ TrimLeft(str, chars);
+ return TrimRight(str, chars);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Trim a string with remove of not wanted spaces at begin of string.
+ ///
+ /// @param[in,out] str String to trim, becomes also changed and given on
+ /// return
+ /// @return The changed string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = "test test ";
+ ///
+ /// std::string varstr = " test test ";
+ /// kodi::tools::StringUtils::TrimLeft(varstr);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string& TrimLeft(std::string& str)
+ {
+ str.erase(str.begin(),
+ std::find_if(str.begin(), str.end(), [](char s) { return IsSpace(s) == 0; }));
+ return str;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Trim a string with remove of not wanted characters at begin of
+ /// string.
+ ///
+ /// @param[in,out] str String to trim, becomes also changed and given on
+ /// return
+ /// @param[in] chars Characters to use for trim
+ /// @return The changed string
+ ///
+ inline static std::string& TrimLeft(std::string& str, const char* const chars)
+ {
+ size_t nidx = str.find_first_not_of(chars);
+ str.erase(0, nidx);
+ return str;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Trim a string with remove of not wanted spaces at end of string.
+ ///
+ /// @param[in,out] str String to trim, becomes also changed and given on
+ /// return
+ /// @return The changed string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = " test test";
+ ///
+ /// std::string varstr = " test test ";
+ /// kodi::tools::StringUtils::TrimRight(varstr);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string& TrimRight(std::string& str)
+ {
+ str.erase(std::find_if(str.rbegin(), str.rend(), [](char s) { return IsSpace(s) == 0; }).base(),
+ str.end());
+ return str;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Trim a string with remove of not wanted characters at end of
+ /// string.
+ ///
+ /// @param[in,out] str String to trim, becomes also changed and given on
+ /// return
+ /// @param[in] chars Characters to use for trim
+ /// @return The changed string
+ ///
+ inline static std::string& TrimRight(std::string& str, const char* const chars)
+ {
+ size_t nidx = str.find_last_not_of(chars);
+ str.erase(str.npos == nidx ? 0 : ++nidx);
+ return str;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Cleanup string by remove of duplicates of spaces and tabs.
+ ///
+ /// @param[in,out] str String to remove duplicates, becomes also changed and
+ /// given further on return
+ /// @return The changed string
+ ///
+ inline static std::string& RemoveDuplicatedSpacesAndTabs(std::string& str)
+ {
+ std::string::iterator it = str.begin();
+ bool onSpace = false;
+ while (it != str.end())
+ {
+ if (*it == '\t')
+ *it = ' ';
+
+ if (*it == ' ')
+ {
+ if (onSpace)
+ {
+ it = str.erase(it);
+ continue;
+ }
+ else
+ onSpace = true;
+ }
+ else
+ onSpace = false;
+
+ ++it;
+ }
+ return str;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Replace a character with another inside text string.
+ ///
+ /// @param[in] str String to replace within
+ /// @param[in] oldChar Character to search for replacement
+ /// @param[in] newChar New character to use for replacement
+ /// @return Amount of replaced characters
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = "text text";
+ ///
+ /// std::string varstr = "test test";
+ /// EXPECT_EQ(kodi::tools::StringUtils::Replace(varstr, 's', 'x'), 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// EXPECT_EQ(kodi::tools::StringUtils::Replace(varstr, 's', 'x'), 0);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static int Replace(std::string& str, char oldChar, char newChar)
+ {
+ int replacedChars = 0;
+ for (std::string::iterator it = str.begin(); it != str.end(); ++it)
+ {
+ if (*it == oldChar)
+ {
+ *it = newChar;
+ replacedChars++;
+ }
+ }
+
+ return replacedChars;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Replace a complete text with another inside text string.
+ ///
+ /// @param[in] str String to replace within
+ /// @param[in] oldStr String to search for replacement
+ /// @param[in] newStr New string to use for replacement
+ /// @return Amount of replaced text fields
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = "text text";
+ ///
+ /// std::string varstr = "test test";
+ /// EXPECT_EQ(kodi::tools::StringUtils::Replace(varstr, "s", "x"), 2);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ ///
+ /// EXPECT_EQ(kodi::tools::StringUtils::Replace(varstr, "s", "x"), 0);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static int Replace(std::string& str, const std::string& oldStr, const std::string& newStr)
+ {
+ if (oldStr.empty())
+ return 0;
+
+ int replacedChars = 0;
+ size_t index = 0;
+
+ while (index < str.size() && (index = str.find(oldStr, index)) != std::string::npos)
+ {
+ str.replace(index, oldStr.size(), newStr);
+ index += newStr.size();
+ replacedChars++;
+ }
+
+ return replacedChars;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Replace a complete text with another inside 16bit wide text string.
+ ///
+ /// @param[in] str String to replace within
+ /// @param[in] oldStr String to search for replacement
+ /// @param[in] newStr New string to use for replacement
+ /// @return Amount of replaced text fields
+ ///
+ inline static int Replace(std::wstring& str,
+ const std::wstring& oldStr,
+ const std::wstring& newStr)
+ {
+ if (oldStr.empty())
+ return 0;
+
+ int replacedChars = 0;
+ size_t index = 0;
+
+ while (index < str.size() && (index = str.find(oldStr, index)) != std::string::npos)
+ {
+ str.replace(index, oldStr.size(), newStr);
+ index += newStr.size();
+ replacedChars++;
+ }
+
+ return replacedChars;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Transform characters to create a safe URL.
+ ///
+ /// @param[in] str The string to transform
+ /// @return The transformed string, with unsafe characters replaced by "_"
+ ///
+ /// Safe URLs are composed of the unreserved characters defined in
+ /// RFC 3986 section 2.3:
+ ///
+ /// ALPHA / DIGIT / "-" / "." / "_" / "~"
+ ///
+ /// Characters outside of this set will be replaced by "_".
+ ///
+ inline static std::string MakeSafeUrl(const std::string& str)
+ {
+ std::string safeUrl;
+
+ safeUrl.reserve(str.size());
+
+ std::transform(str.begin(), str.end(), std::back_inserter(safeUrl), [](char c) {
+ if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '-' ||
+ c == '.' || c == '_' || c == '~')
+ {
+ return c;
+ }
+ return '_';
+ });
+
+ return safeUrl;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Transform characters to create a safe, printable string.
+ ///
+ /// @param[in] str The string to transform
+ /// @return The transformed string, with unsafe characters replaced by " "
+ ///
+ /// Unsafe characters are defined as the non-printable ASCII characters
+ /// (character code 0-31).
+ ///
+ inline static std::string MakeSafeString(const std::string& str)
+ {
+ std::string safeString;
+
+ safeString.reserve(str.size());
+
+ std::transform(str.begin(), str.end(), std::back_inserter(safeString), [](char c) {
+ if (c < 0x20)
+ return ' ';
+
+ return c;
+ });
+
+ return safeString;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Removes a MAC address from a given string.
+ ///
+ /// @param[in] str The string containing a MAC address
+ /// @return The string without the MAC address (for chaining)
+ ///
+ inline static std::string RemoveMACAddress(const std::string& str)
+ {
+ std::regex re(R"mac([\(\[]?([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})[\)\]]?)mac");
+ return std::regex_replace(str, re, "", std::regex_constants::format_default);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Remove carriage return and line feeds on string ends.
+ ///
+ /// @param[in,out] str String where CR and LF becomes removed on end
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr, varstr;
+ ///
+ /// refstr = "test\r\nstring\nblah blah";
+ /// varstr = "test\r\nstring\nblah blah\n";
+ /// kodi::tools::StringUtils::RemoveCRLF(varstr);
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static void RemoveCRLF(std::string& strLine) { StringUtils::TrimRight(strLine, "\n\r"); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Convert a word to a digit numerical string
+ ///
+ /// @param[in] str String to convert
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// std::string ref, var;
+ ///
+ /// ref = "8378 787464";
+ /// var = "test string";
+ /// kodi::tools::StringUtils::WordToDigits(var);
+ /// EXPECT_STREQ(ref.c_str(), var.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static void WordToDigits(std::string& word)
+ {
+ static const char word_to_letter[] = "22233344455566677778889999";
+ StringUtils::ToLower(word);
+ for (unsigned int i = 0; i < word.size(); ++i)
+ { // NB: This assumes ascii, which probably needs extending at some point.
+ char letter = word[i];
+ if ((letter >= 'a' && letter <= 'z')) // assume contiguous letter range
+ {
+ word[i] = word_to_letter[letter - 'a'];
+ }
+ else if (letter < '0' || letter > '9') // We want to keep 0-9!
+ {
+ word[i] = ' '; // replace everything else with a space
+ }
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Escapes the given string to be able to be used as a parameter.
+ ///
+ /// Escapes backslashes and double-quotes with an additional backslash and
+ /// adds double-quotes around the whole string.
+ ///
+ /// @param[in] param String to escape/paramify
+ /// @return Escaped/Paramified string
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// const char *input = "some, very \\ odd \"string\"";
+ /// const char *ref = "\"some, very \\\\ odd \\\"string\\\"\"";
+ ///
+ /// std::string result = kodi::tools::StringUtils::Paramify(input);
+ /// EXPECT_STREQ(ref, result.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string Paramify(const std::string& param)
+ {
+ std::string result = param;
+ // escape backspaces
+ StringUtils::Replace(result, "\\", "\\\\");
+ // escape double quotes
+ StringUtils::Replace(result, "\"", "\\\"");
+
+ // add double quotes around the whole string
+ return "\"" + result + "\"";
+ }
+ //----------------------------------------------------------------------------
+
+ /*!@}*/
+
+ //----------------------------------------------------------------------------
+ /// @defgroup cpp_kodi_tools_StringUtils_CompareControl String compare
+ /// @ingroup cpp_kodi_tools_StringUtils
+ /// @brief **Check strings for the desired state**\n
+ /// With this, texts can be checked to see that they correspond to a required
+ /// format.
+ ///
+ /*!@{*/
+
+ //============================================================================
+ /// @brief Compare two strings with ignore of lower-/uppercase.
+ ///
+ /// @param[in] str1 C++ string to compare
+ /// @param[in] str2 C++ string to compare
+ /// @return True if the strings are equal, false otherwise
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr = "TeSt";
+ ///
+ /// EXPECT_TRUE(kodi::tools::StringUtils::EqualsNoCase(refstr, "TeSt"));
+ /// EXPECT_TRUE(kodi::tools::StringUtils::EqualsNoCase(refstr, "tEsT"));
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static bool EqualsNoCase(const std::string& str1, const std::string& str2)
+ {
+ // before we do the char-by-char comparison, first compare sizes of both strings.
+ // This led to a 33% improvement in benchmarking on average. (size() just returns a member of std::string)
+ if (str1.size() != str2.size())
+ return false;
+ return EqualsNoCase(str1.c_str(), str2.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Compare two strings with ignore of lower-/uppercase.
+ ///
+ /// @param[in] str1 C++ string to compare
+ /// @param[in] s2 C string to compare
+ /// @return True if the strings are equal, false otherwise
+ ///
+ inline static bool EqualsNoCase(const std::string& str1, const char* s2)
+ {
+ return EqualsNoCase(str1.c_str(), s2);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Compare two strings with ignore of lower-/uppercase.
+ ///
+ /// @param[in] s1 C string to compare
+ /// @param[in] s2 C string to compare
+ /// @return True if the strings are equal, false otherwise
+ ///
+ inline static bool EqualsNoCase(const char* s1, const char* s2)
+ {
+ char c2; // we need only one char outside the loop
+ do
+ {
+ const char c1 = *s1++; // const local variable should help compiler to optimize
+ c2 = *s2++;
+ // This includes the possibility that one of the characters is the null-terminator,
+ // which implies a string mismatch.
+ if (c1 != c2 && ::tolower(c1) != ::tolower(c2))
+ return false;
+ } while (c2 != '\0'); // At this point, we know c1 == c2, so there's no need to test them both.
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Compare two strings with ignore of lower-/uppercase with given
+ /// size.
+ ///
+ /// Equal to @ref EqualsNoCase only that size can defined and on return the
+ /// difference between compared character becomes given.
+ ///
+ /// @param[in] str1 C++ string to compare
+ /// @param[in] str2 C++ string to compare
+ /// @param[in] n [opt] Length to check, 0 as default to make complete
+ /// @return 0 if equal, otherwise difference of failed character in string to
+ /// other ("a" - "b" = -1)
+ ///
+ inline static int CompareNoCase(const std::string& str1, const std::string& str2, size_t n = 0)
+ {
+ return CompareNoCase(str1.c_str(), str2.c_str(), n);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Compare two strings with ignore of lower-/uppercase with given
+ /// size.
+ ///
+ /// Equal to @ref EqualsNoCase only that size can defined and on return the
+ /// difference between compared character becomes given.
+ ///
+ /// @param[in] s1 C string to compare
+ /// @param[in] s2 C string to compare
+ /// @param[in] n [opt] Length to check, 0 as default to make complete
+ /// @return 0 if equal, otherwise difference of failed character in string to
+ /// other ("a" - "b" = -1)
+ ///
+ inline static int CompareNoCase(const char* s1, const char* s2, size_t n = 0)
+ {
+ char c2; // we need only one char outside the loop
+ size_t index = 0;
+ do
+ {
+ const char c1 = *s1++; // const local variable should help compiler to optimize
+ c2 = *s2++;
+ index++;
+ // This includes the possibility that one of the characters is the null-terminator,
+ // which implies a string mismatch.
+ if (c1 != c2 && ::tolower(c1) != ::tolower(c2))
+ return ::tolower(c1) - ::tolower(c2);
+ } while (c2 != '\0' &&
+ index != n); // At this point, we know c1 == c2, so there's no need to test them both.
+ return 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the begin of another string.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] str2 C++ string with which text defined in str1 is checked at
+ /// the beginning
+ /// @return True if string started with asked text, false otherwise
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// bool ret;
+ /// std::string refstr = "test";
+ ///
+ /// ret = kodi::tools::StringUtils::StartsWith(refstr, "te");
+ /// fprintf(stderr, "Expect true for here and is '%s'\n", ret ? "true" : "false");
+ ///
+ /// ret = kodi::tools::StringUtils::StartsWith(refstr, "abc");
+ /// fprintf(stderr, "Expect false for here and is '%s'\n", ret ? "true" : "false");
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static bool StartsWith(const std::string& str1, const std::string& str2)
+ {
+ return str1.compare(0, str2.size(), str2) == 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the begin of another string.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] s2 C string with which text defined in str1 is checked at
+ /// the beginning
+ /// @return True if string started with asked text, false otherwise
+ ///
+ inline static bool StartsWith(const std::string& str1, const char* s2)
+ {
+ return StartsWith(str1.c_str(), s2);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the begin of another string.
+ ///
+ /// @param[in] s1 C string to be checked
+ /// @param[in] s2 C string with which text defined in str1 is checked at
+ /// the beginning
+ /// @return True if string started with asked text, false otherwise
+ ///
+ inline static bool StartsWith(const char* s1, const char* s2)
+ {
+ while (*s2 != '\0')
+ {
+ if (*s1 != *s2)
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the begin of another string by ignore of
+ /// upper-/lowercase.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] str2 C++ string with which text defined in str1 is checked at
+ /// the beginning
+ /// @return True if string started with asked text, false otherwise
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// bool ret;
+ /// std::string refstr = "test";
+ ///
+ /// ret = kodi::tools::StringUtils::StartsWithNoCase(refstr, "te");
+ /// fprintf(stderr, "Expect true for here and is '%s'\n", ret ? "true" : "false");
+ ///
+ /// ret = kodi::tools::StringUtils::StartsWithNoCase(refstr, "TEs");
+ /// fprintf(stderr, "Expect true for here and is '%s'\n", ret ? "true" : "false");
+ ///
+ /// ret = kodi::tools::StringUtils::StartsWithNoCase(refstr, "abc");
+ /// fprintf(stderr, "Expect false for here and is '%s'\n", ret ? "true" : "false");
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static bool StartsWithNoCase(const std::string& str1, const std::string& str2)
+ {
+ return StartsWithNoCase(str1.c_str(), str2.c_str());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the begin of another string by ignore of
+ /// upper-/lowercase.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] s2 C string with which text defined in str1 is checked at
+ /// the beginning
+ /// @return True if string started with asked text, false otherwise
+ ///
+ inline static bool StartsWithNoCase(const std::string& str1, const char* s2)
+ {
+ return StartsWithNoCase(str1.c_str(), s2);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the begin of another string by ignore of
+ /// upper-/lowercase.
+ ///
+ /// @param[in] s1 C string to be checked
+ /// @param[in] s2 C string with which text defined in str1 is checked at
+ /// the beginning
+ /// @return True if string started with asked text, false otherwise
+ ///
+ inline static bool StartsWithNoCase(const char* s1, const char* s2)
+ {
+ while (*s2 != '\0')
+ {
+ if (::tolower(*s1) != ::tolower(*s2))
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the ending of another string.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] str2 C++ string with which text defined in str1 is checked at
+ /// the ending
+ /// @return True if string ended with asked text, false otherwise
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// bool ret;
+ /// std::string refstr = "test";
+ ///
+ /// ret = kodi::tools::StringUtils::EndsWith(refstr, "st");
+ /// fprintf(stderr, "Expect true for here and is '%s'\n", ret ? "true" : "false");
+ ///
+ /// ret = kodi::tools::StringUtils::EndsWith(refstr, "abc");
+ /// fprintf(stderr, "Expect false for here and is '%s'\n", ret ? "true" : "false");
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static bool EndsWith(const std::string& str1, const std::string& str2)
+ {
+ if (str1.size() < str2.size())
+ return false;
+ return str1.compare(str1.size() - str2.size(), str2.size(), str2) == 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the ending of another string.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] s2 C string with which text defined in str1 is checked at
+ /// the ending
+ /// @return True if string ended with asked text, false otherwise
+ ///
+ inline static bool EndsWith(const std::string& str1, const char* s2)
+ {
+ size_t len2 = strlen(s2);
+ if (str1.size() < len2)
+ return false;
+ return str1.compare(str1.size() - len2, len2, s2) == 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the ending of another string by ignore of
+ /// upper-/lowercase.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] str2 C++ string with which text defined in str1 is checked at
+ /// the ending
+ /// @return True if string ended with asked text, false otherwise
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// bool ret;
+ /// std::string refstr = "test";
+ ///
+ /// ret = kodi::tools::StringUtils::EndsWithNoCase(refstr, "ST");
+ /// fprintf(stderr, "Expect true for here and is '%s'\n", ret ? "true" : "false");
+ ///
+ /// ret = kodi::tools::StringUtils::EndsWithNoCase(refstr, "ABC");
+ /// fprintf(stderr, "Expect false for here and is '%s'\n", ret ? "true" : "false");
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static bool EndsWithNoCase(const std::string& str1, const std::string& str2)
+ {
+ if (str1.size() < str2.size())
+ return false;
+ const char* s1 = str1.c_str() + str1.size() - str2.size();
+ const char* s2 = str2.c_str();
+ while (*s2 != '\0')
+ {
+ if (::tolower(*s1) != ::tolower(*s2))
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a string for the ending of another string by ignore of
+ /// upper-/lowercase.
+ ///
+ /// @param[in] str1 C++ string to be checked
+ /// @param[in] s2 C string with which text defined in str1 is checked at
+ /// the ending
+ /// @return True if string ended with asked text, false otherwise
+ ///
+ inline static bool EndsWithNoCase(const std::string& str1, const char* s2)
+ {
+ size_t len2 = strlen(s2);
+ if (str1.size() < len2)
+ return false;
+ const char* s1 = str1.c_str() + str1.size() - len2;
+ while (*s2 != '\0')
+ {
+ if (::tolower(*s1) != ::tolower(*s2))
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Compare two strings by his calculated alpha numeric values.
+ ///
+ /// @param[in] left Left string to compare with right
+ /// @param[in] right Right string to compare with left
+ /// @return Return about compare
+ /// - 0 if left and right the same
+ /// - -1 if right is longer
+ /// - 1 if left is longer
+ /// - < 0 if less equal
+ /// - > 0 if more equal
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// int64_t ref, var;
+ ///
+ /// ref = 0;
+ /// var = kodi::tools::StringUtils::AlphaNumericCompare(L"123abc", L"abc123");
+ /// EXPECT_LT(var, ref);
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static int64_t AlphaNumericCompare(const wchar_t* left, const wchar_t* right)
+ {
+ const wchar_t* l = left;
+ const wchar_t* r = right;
+ const wchar_t *ld, *rd;
+ wchar_t lc, rc;
+ int64_t lnum, rnum;
+ const std::collate<wchar_t>& coll = std::use_facet<std::collate<wchar_t>>(std::locale());
+ int cmp_res = 0;
+ while (*l != 0 && *r != 0)
+ {
+ // check if we have a numerical value
+ if (*l >= L'0' && *l <= L'9' && *r >= L'0' && *r <= L'9')
+ {
+ ld = l;
+ lnum = 0;
+ while (*ld >= L'0' && *ld <= L'9' && ld < l + 15)
+ { // compare only up to 15 digits
+ lnum *= 10;
+ lnum += *ld++ - '0';
+ }
+ rd = r;
+ rnum = 0;
+ while (*rd >= L'0' && *rd <= L'9' && rd < r + 15)
+ { // compare only up to 15 digits
+ rnum *= 10;
+ rnum += *rd++ - L'0';
+ }
+ // do we have numbers?
+ if (lnum != rnum)
+ { // yes - and they're different!
+ return lnum - rnum;
+ }
+ l = ld;
+ r = rd;
+ continue;
+ }
+ // do case less comparison
+ lc = *l;
+ if (lc >= L'A' && lc <= L'Z')
+ lc += L'a' - L'A';
+ rc = *r;
+ if (rc >= L'A' && rc <= L'Z')
+ rc += L'a' - L'A';
+
+ // ok, do a normal comparison, taking current locale into account. Add special case stuff (eg '(' characters)) in here later
+ if ((cmp_res = coll.compare(&lc, &lc + 1, &rc, &rc + 1)) != 0)
+ {
+ return cmp_res;
+ }
+ l++;
+ r++;
+ }
+ if (*r)
+ { // r is longer
+ return -1;
+ }
+ else if (*l)
+ { // l is longer
+ return 1;
+ }
+ return 0; // files are the same
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief UTF8 version of strlen
+ ///
+ /// Skips any non-starting bytes in the count, thus returning the number of
+ /// utf8 characters.
+ ///
+ /// @param[in] s c-string to find the length of.
+ /// @return The number of utf8 characters in the string.
+ ///
+ inline static size_t Utf8StringLength(const char* s)
+ {
+ size_t length = 0;
+ while (*s)
+ {
+ if ((*s++ & 0xC0) != 0x80)
+ length++;
+ }
+ return length;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Check given character is a space.
+ ///
+ /// Hack to check only first byte of UTF-8 character
+ /// without this hack "TrimX" functions failed on Win32 and OS X with UTF-8 strings
+ ///
+ /// @param[in] c Character to check
+ /// @return true if space, false otherwise
+ ///
+ inline static int IsSpace(char c) { return (c & 0x80) == 0 && ::isspace(c); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks given pointer in string is a UTF8 letter.
+ ///
+ /// @param[in] str Given character values to check, must be minimum array of 2
+ /// @return return -1 if not, else return the utf8 char length.
+ ///
+ inline static int IsUTF8Letter(const unsigned char* str)
+ {
+ // reference:
+ // unicode -> utf8 table: http://www.utf8-chartable.de/
+ // latin characters in unicode: http://en.wikipedia.org/wiki/Latin_characters_in_Unicode
+ unsigned char ch = str[0];
+ if (!ch)
+ return -1;
+ if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
+ return 1;
+ if (!(ch & 0x80))
+ return -1;
+ unsigned char ch2 = str[1];
+ if (!ch2)
+ return -1;
+ // check latin 1 letter table: http://en.wikipedia.org/wiki/C1_Controls_and_Latin-1_Supplement
+ if (ch == 0xC3 && ch2 >= 0x80 && ch2 <= 0xBF && ch2 != 0x97 && ch2 != 0xB7)
+ return 2;
+ // check latin extended A table: http://en.wikipedia.org/wiki/Latin_Extended-A
+ if (ch >= 0xC4 && ch <= 0xC7 && ch2 >= 0x80 && ch2 <= 0xBF)
+ return 2;
+ // check latin extended B table: http://en.wikipedia.org/wiki/Latin_Extended-B
+ // and International Phonetic Alphabet: http://en.wikipedia.org/wiki/IPA_Extensions_(Unicode_block)
+ if (((ch == 0xC8 || ch == 0xC9) && ch2 >= 0x80 && ch2 <= 0xBF) ||
+ (ch == 0xCA && ch2 >= 0x80 && ch2 <= 0xAF))
+ return 2;
+ return -1;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Check whether a string is a natural number.
+ ///
+ /// Matches `[ \t]*[0-9]+[ \t]*`
+ ///
+ /// @param[in] str The string to check
+ /// @return true if the string is a natural number, false otherwise.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// EXPECT_TRUE(kodi::tools::StringUtils::IsNaturalNumber("10"));
+ /// EXPECT_TRUE(kodi::tools::StringUtils::IsNaturalNumber(" 10"));
+ /// EXPECT_TRUE(kodi::tools::StringUtils::IsNaturalNumber("0"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber(" 1 0"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber("1.0"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber("1.1"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber("0x1"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber("blah"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber("120 h"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber(" "));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsNaturalNumber(""));
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static bool IsNaturalNumber(const std::string& str)
+ {
+ size_t i = 0, n = 0;
+ // allow whitespace,digits,whitespace
+ while (i < str.size() && isspace((unsigned char)str[i]))
+ i++;
+ while (i < str.size() && isdigit((unsigned char)str[i]))
+ {
+ i++;
+ n++;
+ }
+ while (i < str.size() && isspace((unsigned char)str[i]))
+ i++;
+ return i == str.size() && n > 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Check whether a string is an integer.
+ ///
+ /// Matches `[ \t]*[\-]*[0-9]+[ \t]*`
+ ///
+ /// @param str The string to check
+ /// @return true if the string is an integer, false otherwise.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// EXPECT_TRUE(kodi::tools::StringUtils::IsInteger("10"));
+ /// EXPECT_TRUE(kodi::tools::StringUtils::IsInteger(" -10"));
+ /// EXPECT_TRUE(kodi::tools::StringUtils::IsInteger("0"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger(" 1 0"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger("1.0"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger("1.1"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger("0x1"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger("blah"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger("120 h"));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger(" "));
+ /// EXPECT_FALSE(kodi::tools::StringUtils::IsInteger(""));
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static bool IsInteger(const std::string& str)
+ {
+ size_t i = 0, n = 0;
+ // allow whitespace,-,digits,whitespace
+ while (i < str.size() && isspace((unsigned char)str[i]))
+ i++;
+ if (i < str.size() && str[i] == '-')
+ i++;
+ while (i < str.size() && isdigit((unsigned char)str[i]))
+ {
+ i++;
+ n++;
+ }
+ while (i < str.size() && isspace((unsigned char)str[i]))
+ i++;
+ return i == str.size() && n > 0;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a character is ascii number.
+ ///
+ /// @param[in] chr Single character to test
+ /// @return true if yes, false otherwise
+ ///
+ inline static bool IsAasciiDigit(char chr) // locale independent
+ {
+ return chr >= '0' && chr <= '9';
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a character is ascii hexadecimal number.
+ ///
+ /// @param[in] chr Single character to test
+ /// @return true if yes, false otherwise
+ ///
+ inline static bool IsAsciiXDigit(char chr) // locale independent
+ {
+ return (chr >= '0' && chr <= '9') || (chr >= 'a' && chr <= 'f') || (chr >= 'A' && chr <= 'F');
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Translate a character where defined as a numerical value (0-9)
+ /// string to right integer.
+ ///
+ /// @param[in] chr Single character to translate
+ /// @return
+ ///
+ inline static int AsciiDigitValue(char chr) // locale independent
+ {
+ if (!IsAasciiDigit(chr))
+ return -1;
+
+ return chr - '0';
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Translate a character where defined as a hexadecimal value string
+ /// to right integer.
+ ///
+ /// @param[in] chr Single character to translate
+ /// @return Corresponding integer value, e.g. character is "A" becomes
+ /// returned as a integer with 10.
+ ///
+ inline static int AsciiXDigitValue(char chr) // locale independent
+ {
+ int v = AsciiDigitValue(chr);
+ if (v >= 0)
+ return v;
+ if (chr >= 'a' && chr <= 'f')
+ return chr - 'a' + 10;
+ if (chr >= 'A' && chr <= 'F')
+ return chr - 'A' + 10;
+
+ return -1;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a character is ascii alphabetic lowercase.
+ ///
+ /// @param[in] chr Single character to test
+ /// @return True if ascii uppercase letter, false otherwise
+ ///
+ inline static bool IsAsciiUppercaseLetter(char chr) // locale independent
+ {
+ return (chr >= 'A' && chr <= 'Z');
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a character is ascii alphabetic lowercase.
+ ///
+ /// @param[in] chr Single character to test
+ /// @return True if ascii lowercase letter, false otherwise
+ ///
+ inline static bool IsAsciiLowercaseLetter(char chr) // locale independent
+ {
+ return (chr >= 'a' && chr <= 'z');
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Checks a character is within ascii alphabetic and numerical fields.
+ ///
+ /// @param[in] chr Single character to test
+ /// @return true if alphabetic / numerical ascii value
+ ///
+ inline static bool IsAsciiAlphaNum(char chr) // locale independent
+ {
+ return IsAsciiUppercaseLetter(chr) || IsAsciiLowercaseLetter(chr) || IsAasciiDigit(chr);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Check a string for another text.
+ ///
+ /// @param[in] str String to search for keywords
+ /// @param[in] keywords List of keywords to search in text
+ /// @return true if string contains word in list
+ ///
+ inline static bool ContainsKeyword(const std::string& str,
+ const std::vector<std::string>& keywords)
+ {
+ for (const auto& it : keywords)
+ {
+ if (str.find(it) != str.npos)
+ return true;
+ }
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ /*!@}*/
+
+ //----------------------------------------------------------------------------
+ /// @defgroup cpp_kodi_tools_StringUtils_SearchControl String search
+ /// @ingroup cpp_kodi_tools_StringUtils
+ /// @brief **To search a string**\n
+ /// Various functions are defined in here which allow you to search through a
+ /// text in different ways.
+ ///
+ /*!@{*/
+
+ //============================================================================
+ /// @brief Search for a single word within a text.
+ ///
+ /// @param[in] str String to search within
+ /// @param[in] wordLowerCase Word as lowercase to search
+ /// @return Position in string where word is found, -1 (std::string::npos) if
+ /// not found
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// size_t ref, var;
+ ///
+ /// // The name "string" is alone within text and becomes found on position 5
+ /// ref = 5;
+ /// var = kodi::tools::StringUtils::FindWords("test string", "string");
+ /// EXPECT_EQ(ref, var);
+ ///
+ /// // The 12 is included inside another word and then not found as it should alone (-1 return)
+ /// ref = -1;
+ /// var = kodi::tools::StringUtils::FindWords("apple2012", "12");
+ /// EXPECT_EQ(ref, var);
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static size_t FindWords(const char* str, const char* wordLowerCase)
+ {
+ // NOTE: This assumes word is lowercase!
+ const unsigned char* s = (const unsigned char*)str;
+ do
+ {
+ // start with a compare
+ const unsigned char* c = s;
+ const unsigned char* w = (const unsigned char*)wordLowerCase;
+ bool same = true;
+ while (same && *c && *w)
+ {
+ unsigned char lc = *c++;
+ if (lc >= 'A' && lc <= 'Z')
+ lc += 'a' - 'A';
+
+ if (lc != *w++) // different
+ same = false;
+ }
+ if (same && *w == 0) // only the same if word has been exhausted
+ return (const char*)s - str;
+
+ // otherwise, skip current word (composed by latin letters) or number
+ int l;
+ if (*s >= '0' && *s <= '9')
+ {
+ ++s;
+ while (*s >= '0' && *s <= '9')
+ ++s;
+ }
+ else if ((l = IsUTF8Letter(s)) > 0)
+ {
+ s += l;
+ while ((l = IsUTF8Letter(s)) > 0)
+ s += l;
+ }
+ else
+ ++s;
+ while (*s && *s == ' ')
+ s++;
+
+ // and repeat until we're done
+ } while (*s);
+
+ return std::string::npos;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Search a string for a given bracket and give its end position.
+ ///
+ /// @param[in] str String to search within
+ /// @param[in] opener Begin character to start search
+ /// @param[in] closer End character to end search
+ /// @param[in] startPos [opt] Position to start search in string, 0 as default
+ /// to start from begin
+ /// @return End position where found, -1 if failed
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// int ref, var;
+ ///
+ /// ref = 11;
+ /// var = kodi::tools::StringUtils::FindEndBracket("atest testbb test", 'a', 'b');
+ /// EXPECT_EQ(ref, var);
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static size_t FindEndBracket(const std::string& str,
+ char opener,
+ char closer,
+ size_t startPos = 0)
+ {
+ size_t blocks = 1;
+ for (size_t i = startPos; i < str.size(); i++)
+ {
+ if (str[i] == opener)
+ blocks++;
+ else if (str[i] == closer)
+ {
+ blocks--;
+ if (!blocks)
+ return i;
+ }
+ }
+
+ return std::string::npos;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Search a text and return the number of parts found as a number.
+ ///
+ /// @param[in] strInput Input string to search for
+ /// @param[in] strFind String to search in input
+ /// @return Amount how much the string is found
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// EXPECT_EQ(3, kodi::tools::StringUtils::FindNumber("aabcaadeaa", "aa"));
+ /// EXPECT_EQ(1, kodi::tools::StringUtils::FindNumber("aabcaadeaa", "b"));
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static int FindNumber(const std::string& strInput, const std::string& strFind)
+ {
+ size_t pos = strInput.find(strFind, 0);
+ int numfound = 0;
+ while (pos != std::string::npos)
+ {
+ numfound++;
+ pos = strInput.find(strFind, pos + 1);
+ }
+ return numfound;
+ }
+ //----------------------------------------------------------------------------
+
+ /*!@}*/
+
+ //----------------------------------------------------------------------------
+ /// @defgroup cpp_kodi_tools_StringUtils_ListControl String list
+ /// @ingroup cpp_kodi_tools_StringUtils
+ /// @brief **Creating lists using a string**\n
+ /// With this, either simple vectors or lists defined by templates can be given
+ /// for the respective divided text.
+ ///
+ /*!@{*/
+
+ //============================================================================
+ /// @brief Concatenates the elements of a specified array or the members of a
+ /// collection and uses the specified separator between each element or
+ /// member.
+ ///
+ /// @param[in] strings An array of objects whose string representations are
+ /// concatenated.
+ /// @param[in] delimiter Delimiter to be used to join the input string
+ /// @return A string consisting of the elements of values, separated by the
+ /// separator character.
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string refstr, varstr;
+ /// std::vector<std::string> strarray;
+ ///
+ /// strarray.emplace_back("a");
+ /// strarray.emplace_back("b");
+ /// strarray.emplace_back("c");
+ /// strarray.emplace_back("de");
+ /// strarray.emplace_back(",");
+ /// strarray.emplace_back("fg");
+ /// strarray.emplace_back(",");
+ /// refstr = "a,b,c,de,,,fg,,";
+ /// varstr = kodi::tools::StringUtils::Join(strarray, ",");
+ /// EXPECT_STREQ(refstr.c_str(), varstr.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ template<typename CONTAINER>
+ inline static std::string Join(const CONTAINER& strings, const std::string& delimiter)
+ {
+ std::string result;
+ for (const auto& str : strings)
+ result += str + delimiter;
+
+ if (!result.empty())
+ result.erase(result.size() - delimiter.size());
+ return result;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Splits the given input string using the given delimiter into
+ /// separate strings.
+ ///
+ /// If the given input string is empty the result will be an empty array (not
+ /// an array containing an empty string).
+ ///
+ /// @param[in] input Input string to be split
+ /// @param[in] delimiter Delimiter to be used to split the input string
+ /// @param[in] iMaxStrings [opt] Maximum number of resulting split strings
+ /// @return List of splitted strings
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::vector<std::string> varresults;
+ ///
+ /// varresults = kodi::tools::StringUtils::Split("g,h,ij,k,lm,,n", ",");
+ /// EXPECT_STREQ("g", varresults.at(0).c_str());
+ /// EXPECT_STREQ("h", varresults.at(1).c_str());
+ /// EXPECT_STREQ("ij", varresults.at(2).c_str());
+ /// EXPECT_STREQ("k", varresults.at(3).c_str());
+ /// EXPECT_STREQ("lm", varresults.at(4).c_str());
+ /// EXPECT_STREQ("", varresults.at(5).c_str());
+ /// EXPECT_STREQ("n", varresults.at(6).c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::vector<std::string> Split(const std::string& input,
+ const std::string& delimiter,
+ unsigned int iMaxStrings = 0)
+ {
+ std::vector<std::string> result;
+ SplitTo(std::back_inserter(result), input, delimiter, iMaxStrings);
+ return result;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Splits the given input string using the given delimiter into
+ /// separate strings.
+ ///
+ /// If the given input string is empty the result will be an empty array (not
+ /// an array containing an empty string).
+ ///
+ /// @param[in] input Input string to be split
+ /// @param[in] delimiter Delimiter to be used to split the input string
+ /// @param[in] iMaxStrings [opt] Maximum number of resulting split strings
+ /// @return List of splitted strings
+ ///
+ inline static std::vector<std::string> Split(const std::string& input,
+ const char delimiter,
+ int iMaxStrings = 0)
+ {
+ std::vector<std::string> result;
+ SplitTo(std::back_inserter(result), input, delimiter, iMaxStrings);
+ return result;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Splits the given input string using the given delimiter into
+ /// separate strings.
+ ///
+ /// If the given input string is empty the result will be an empty array (not
+ /// an array containing an empty string).
+ ///
+ /// @param[in] input Input string to be split
+ /// @param[in] delimiters Delimiter strings to be used to split the input
+ /// strings
+ /// @return List of splitted strings
+ ///
+ inline static std::vector<std::string> Split(const std::string& input,
+ const std::vector<std::string>& delimiters)
+ {
+ std::vector<std::string> result;
+ SplitTo(std::back_inserter(result), input, delimiters);
+ return result;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Splits the given input string using the given delimiter into
+ /// separate strings.
+ ///
+ /// If the given input string is empty nothing will be put into the target
+ /// iterator.
+ ///
+ /// @param[in] d_first The beginning of the destination range
+ /// @param[in] input Input string to be split
+ /// @param[in] delimiter Delimiter to be used to split the input string
+ /// @param[in] iMaxStrings [opt] Maximum number of resulting split strings
+ /// @return Output iterator to the element in the destination range, one past
+ /// the last element that was put there
+ ///
+ template<typename OutputIt>
+ inline static OutputIt SplitTo(OutputIt d_first,
+ const std::string& input,
+ const std::string& delimiter,
+ unsigned int iMaxStrings = 0)
+ {
+ OutputIt dest = d_first;
+
+ if (input.empty())
+ return dest;
+ if (delimiter.empty())
+ {
+ *d_first++ = input;
+ return dest;
+ }
+
+ const size_t delimLen = delimiter.length();
+ size_t nextDelim;
+ size_t textPos = 0;
+ do
+ {
+ if (--iMaxStrings == 0)
+ {
+ *dest++ = input.substr(textPos);
+ break;
+ }
+ nextDelim = input.find(delimiter, textPos);
+ *dest++ = input.substr(textPos, nextDelim - textPos);
+ textPos = nextDelim + delimLen;
+ } while (nextDelim != std::string::npos);
+
+ return dest;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Splits the given input string using the given delimiter into
+ /// separate strings.
+ ///
+ /// If the given input string is empty nothing will be put into the target
+ /// iterator.
+ ///
+ /// @param[in] d_first The beginning of the destination range
+ /// @param[in] input Input string to be split
+ /// @param[in] delimiter Delimiter to be used to split the input string
+ /// @param[in] iMaxStrings [opt] Maximum number of resulting split strings
+ /// @return Output iterator to the element in the destination range, one past
+ /// the last element that was put there
+ ///
+ template<typename OutputIt>
+ inline static OutputIt SplitTo(OutputIt d_first,
+ const std::string& input,
+ const char delimiter,
+ int iMaxStrings = 0)
+ {
+ return SplitTo(d_first, input, std::string(1, delimiter), iMaxStrings);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Splits the given input string using the given delimiter into
+ /// separate strings.
+ ///
+ /// If the given input string is empty nothing will be put into the target
+ /// iterator.
+ ///
+ /// @param[in] d_first The beginning of the destination range
+ /// @param[in] input Input string to be split
+ /// @param[in] delimiters Delimiter strings to be used to split the input
+ /// strings
+ /// @return Output iterator to the element in the destination range, one past
+ /// the last element that was put there
+ ///
+ template<typename OutputIt>
+ inline static OutputIt SplitTo(OutputIt d_first,
+ const std::string& input,
+ const std::vector<std::string>& delimiters)
+ {
+ OutputIt dest = d_first;
+ if (input.empty())
+ return dest;
+
+ if (delimiters.empty())
+ {
+ *dest++ = input;
+ return dest;
+ }
+ std::string str = input;
+ for (size_t di = 1; di < delimiters.size(); di++)
+ StringUtils::Replace(str, delimiters[di], delimiters[0]);
+ return SplitTo(dest, str, delimiters[0]);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Splits the given input strings using the given delimiters into
+ /// further separate strings.
+ ///
+ /// If the given input string vector is empty the result will be an empty
+ /// array (not an array containing an empty string).
+ ///
+ /// Delimiter strings are applied in order, so once the (optional) maximum
+ /// number of items is produced no other delimiters are applied. This produces
+ /// different results to applying all delimiters at once e.g. "a/b#c/d"
+ /// becomes "a", "b#c", "d" rather than "a", "b", "c/d"
+ ///
+ /// @param[in] input Input vector of strings each to be split
+ /// @param[in] delimiters Delimiter strings to be used to split the input
+ /// strings
+ /// @param[in] iMaxStrings [opt] Maximum number of resulting split strings
+ /// @return List of splitted strings
+ ///
+ inline static std::vector<std::string> SplitMulti(const std::vector<std::string>& input,
+ const std::vector<std::string>& delimiters,
+ unsigned int iMaxStrings = 0)
+ {
+ if (input.empty())
+ return std::vector<std::string>();
+
+ std::vector<std::string> results(input);
+
+ if (delimiters.empty() || (iMaxStrings > 0 && iMaxStrings <= input.size()))
+ return results;
+
+ std::vector<std::string> strings1;
+ if (iMaxStrings == 0)
+ {
+ for (size_t di = 0; di < delimiters.size(); di++)
+ {
+ for (size_t i = 0; i < results.size(); i++)
+ {
+ std::vector<std::string> substrings = StringUtils::Split(results[i], delimiters[di]);
+ for (size_t j = 0; j < substrings.size(); j++)
+ strings1.push_back(substrings[j]);
+ }
+ results = strings1;
+ strings1.clear();
+ }
+ return results;
+ }
+
+ // Control the number of strings input is split into, keeping the original strings.
+ // Note iMaxStrings > input.size()
+ size_t iNew = iMaxStrings - results.size();
+ for (size_t di = 0; di < delimiters.size(); di++)
+ {
+ for (size_t i = 0; i < results.size(); i++)
+ {
+ if (iNew > 0)
+ {
+ std::vector<std::string> substrings =
+ StringUtils::Split(results[i], delimiters[di], static_cast<int>(iNew + 1));
+ iNew = iNew - substrings.size() + 1;
+ for (size_t j = 0; j < substrings.size(); j++)
+ strings1.push_back(substrings[j]);
+ }
+ else
+ strings1.push_back(results[i]);
+ }
+ results = strings1;
+ iNew = iMaxStrings - results.size();
+ strings1.clear();
+ if ((iNew <= 0))
+ break; //Stop trying any more delimiters
+ }
+ return results;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Split a string by the specified delimiters.
+ ///
+ /// Splits a string using one or more delimiting characters, ignoring empty
+ /// tokens.
+ ///
+ /// Differs from Split() in two ways:
+ /// 1. The delimiters are treated as individual characters, rather than a single delimiting string.
+ /// 2. Empty tokens are ignored.
+ ///
+ ///
+ /// @param[in] input String to split
+ /// @param[in] delimiters Delimiters
+ /// @return A vector of tokens
+ ///
+ inline static std::vector<std::string> Tokenize(const std::string& input,
+ const std::string& delimiters)
+ {
+ std::vector<std::string> tokens;
+ Tokenize(input, tokens, delimiters);
+ return tokens;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Tokenizing a string denotes splitting a string with respect to a
+ /// delimiter.
+ ///
+ /// @param[in] input String to split
+ /// @param[out] tokens A vector of tokens
+ /// @param[in] delimiters Delimiters
+ ///
+ inline static void Tokenize(const std::string& input,
+ std::vector<std::string>& tokens,
+ const std::string& delimiters)
+ {
+ tokens.clear();
+ // Skip delimiters at beginning.
+ std::string::size_type dataPos = input.find_first_not_of(delimiters);
+ while (dataPos != std::string::npos)
+ {
+ // Find next delimiter
+ const std::string::size_type nextDelimPos = input.find_first_of(delimiters, dataPos);
+ // Found a token, add it to the vector.
+ tokens.push_back(input.substr(dataPos, nextDelimPos - dataPos));
+ // Skip delimiters. Note the "not_of"
+ dataPos = input.find_first_not_of(delimiters, nextDelimPos);
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Tokenizing a string denotes splitting a string with respect to a
+ /// delimiter.
+ ///
+ /// @param[in] input String to split
+ /// @param[in] delimiter Delimiters
+ /// @return A vector of tokens
+ ///
+ inline static std::vector<std::string> Tokenize(const std::string& input, const char delimiter)
+ {
+ std::vector<std::string> tokens;
+ Tokenize(input, tokens, delimiter);
+ return tokens;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Tokenizing a string denotes splitting a string with respect to a
+ /// delimiter.
+ ///
+ /// @param[in] input String to split
+ /// @param[out] tokens List of
+ /// @param[in] delimiter Delimiters
+ ///
+ inline static void Tokenize(const std::string& input,
+ std::vector<std::string>& tokens,
+ const char delimiter)
+ {
+ tokens.clear();
+ // Skip delimiters at beginning.
+ std::string::size_type dataPos = input.find_first_not_of(delimiter);
+ while (dataPos != std::string::npos)
+ {
+ // Find next delimiter
+ const std::string::size_type nextDelimPos = input.find(delimiter, dataPos);
+ // Found a token, add it to the vector.
+ tokens.push_back(input.substr(dataPos, nextDelimPos - dataPos));
+ // Skip delimiters. Note the "not_of"
+ dataPos = input.find_first_not_of(delimiter, nextDelimPos);
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ /*!@}*/
+
+ //----------------------------------------------------------------------------
+ /// @defgroup cpp_kodi_tools_StringUtils_TimeControl Time value processing
+ /// @ingroup cpp_kodi_tools_StringUtils
+ /// @brief **String time formats**\n
+ /// This is used to process the respective time formats in text fields.
+ /*!@{*/
+
+ //============================================================================
+ /// @brief Converts a time string to the respective integer value.
+ ///
+ /// @param[in] timeString String with time.\n
+ /// Following types are possible:
+ /// - "MM min" (integer number with "min" on end)
+ /// - "HH:MM:SS"
+ /// @return Time in seconds
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// EXPECT_EQ(77455, kodi::tools::StringUtils::TimeStringToSeconds("21:30:55"));
+ /// EXPECT_EQ(7*60, kodi::tools::StringUtils::TimeStringToSeconds("7 min"));
+ /// EXPECT_EQ(7*60, kodi::tools::StringUtils::TimeStringToSeconds("7 min\t"));
+ /// EXPECT_EQ(154*60, kodi::tools::StringUtils::TimeStringToSeconds(" 154 min"));
+ /// EXPECT_EQ(1*60+1, kodi::tools::StringUtils::TimeStringToSeconds("1:01"));
+ /// EXPECT_EQ(4*60+3, kodi::tools::StringUtils::TimeStringToSeconds("4:03"));
+ /// EXPECT_EQ(2*3600+4*60+3, kodi::tools::StringUtils::TimeStringToSeconds("2:04:03"));
+ /// EXPECT_EQ(2*3600+4*60+3, kodi::tools::StringUtils::TimeStringToSeconds(" 2:4:3"));
+ /// EXPECT_EQ(2*3600+4*60+3, kodi::tools::StringUtils::TimeStringToSeconds(" \t\t 02:04:03 \n "));
+ /// EXPECT_EQ(1*3600+5*60+2, kodi::tools::StringUtils::TimeStringToSeconds("01:05:02:04:03 \n "));
+ /// EXPECT_EQ(0, kodi::tools::StringUtils::TimeStringToSeconds("blah"));
+ /// EXPECT_EQ(0, kodi::tools::StringUtils::TimeStringToSeconds("ля-ля"));
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static long TimeStringToSeconds(const std::string& timeString)
+ {
+ std::string strCopy(timeString);
+ StringUtils::Trim(strCopy);
+ if (StringUtils::EndsWithNoCase(strCopy, " min"))
+ {
+ // this is imdb format of "XXX min"
+ return 60 * atoi(strCopy.c_str());
+ }
+ else
+ {
+ std::vector<std::string> secs = StringUtils::Split(strCopy, ':');
+ int timeInSecs = 0;
+ for (unsigned int i = 0; i < 3 && i < secs.size(); i++)
+ {
+ timeInSecs *= 60;
+ timeInSecs += atoi(secs[i].c_str());
+ }
+ return timeInSecs;
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Convert a time in seconds to a string based on the given time
+ /// format.
+ ///
+ /// @param[in] seconds time in seconds
+ /// @param[in] format [opt] The format we want the time in
+ /// @return The formatted time
+ ///
+ /// @sa TIME_FORMAT
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// std::string ref, var;
+ ///
+ /// ref = "21:30:55";
+ /// var = kodi::tools::StringUtils::SecondsToTimeString(77455);
+ /// EXPECT_STREQ(ref.c_str(), var.c_str());
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static std::string SecondsToTimeString(long seconds,
+ TIME_FORMAT format = TIME_FORMAT_GUESS)
+ {
+ bool isNegative = seconds < 0;
+ seconds = std::abs(seconds);
+
+ std::string strHMS;
+ if (format == TIME_FORMAT_SECS)
+ strHMS = std::to_string(seconds);
+ else if (format == TIME_FORMAT_MINS)
+ strHMS = std::to_string(lrintf(static_cast<float>(seconds) / 60.0f));
+ else if (format == TIME_FORMAT_HOURS)
+ strHMS = std::to_string(lrintf(static_cast<float>(seconds) / 3600.0f));
+ else if (format & TIME_FORMAT_M)
+ strHMS += std::to_string(seconds % 3600 / 60);
+ else
+ {
+ int hh = seconds / 3600;
+ seconds = seconds % 3600;
+ int mm = seconds / 60;
+ int ss = seconds % 60;
+
+ if (format == TIME_FORMAT_GUESS)
+ format = (hh >= 1) ? TIME_FORMAT_HH_MM_SS : TIME_FORMAT_MM_SS;
+ if (format & TIME_FORMAT_HH)
+ strHMS += StringUtils::Format("{:02}", hh);
+ else if (format & TIME_FORMAT_H)
+ strHMS += std::to_string(hh);
+ if (format & TIME_FORMAT_MM)
+ strHMS += StringUtils::Format(strHMS.empty() ? "{:02}" : ":{:02}", mm);
+ if (format & TIME_FORMAT_SS)
+ strHMS += StringUtils::Format(strHMS.empty() ? "{:02}" : ":{:02}", ss);
+ }
+
+ if (isNegative)
+ strHMS = "-" + strHMS;
+
+ return strHMS;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Converts a string in the format YYYYMMDD to the corresponding
+ /// integer value.
+ ///
+ /// @param[in] dateString The date in the associated format, possible values
+ /// are:
+ /// - DD (for days only)
+ /// - MM-DD (for days with month)
+ /// - YYYY-MM-DD (for years, then month and last days)
+ /// @return Corresponding integer, e.g. "2020-12-24" return as integer value
+ /// 20201224
+ ///
+ ///
+ /// --------------------------------------------------------------------------
+ /// Example:
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/StringUtils.h>
+ ///
+ /// int ref, var;
+ ///
+ /// ref = 20120706;
+ /// var = kodi::tools::StringUtils::DateStringToYYYYMMDD("2012-07-06");
+ /// EXPECT_EQ(ref, var);
+ /// ~~~~~~~~~~~~~
+ ///
+ inline static int DateStringToYYYYMMDD(const std::string& dateString)
+ {
+ std::vector<std::string> days = StringUtils::Split(dateString, '-');
+ if (days.size() == 1)
+ return atoi(days[0].c_str());
+ else if (days.size() == 2)
+ return atoi(days[0].c_str()) * 100 + atoi(days[1].c_str());
+ else if (days.size() == 3)
+ return atoi(days[0].c_str()) * 10000 + atoi(days[1].c_str()) * 100 + atoi(days[2].c_str());
+ else
+ return -1;
+ }
+ //----------------------------------------------------------------------------
+
+ /*!@}*/
+
+private:
+ inline static int compareWchar(const void* a, const void* b)
+ {
+ if (*static_cast<const wchar_t*>(a) < *static_cast<const wchar_t*>(b))
+ return -1;
+ else if (*static_cast<const wchar_t*>(a) > *static_cast<const wchar_t*>(b))
+ return 1;
+ return 0;
+ }
+
+ inline static wchar_t tolowerUnicode(const wchar_t& c)
+ {
+ wchar_t* p =
+ static_cast<wchar_t*>(bsearch(&c, unicode_uppers, sizeof(unicode_uppers) / sizeof(wchar_t),
+ sizeof(wchar_t), compareWchar));
+ if (p)
+ return *(unicode_lowers + (p - unicode_uppers));
+
+ return c;
+ }
+
+ inline static wchar_t toupperUnicode(const wchar_t& c)
+ {
+ wchar_t* p =
+ static_cast<wchar_t*>(bsearch(&c, unicode_lowers, sizeof(unicode_lowers) / sizeof(wchar_t),
+ sizeof(wchar_t), compareWchar));
+ if (p)
+ return *(unicode_uppers + (p - unicode_lowers));
+
+ return c;
+ }
+
+ static uint32_t UTF8ToUnicode(const unsigned char* z, int nKey, unsigned char& bytes)
+ {
+ // Lookup table used decode the first byte of a multi-byte UTF8 character
+ // clang-format off
+ static const unsigned char utf8Trans1[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
+ };
+ // clang-format on
+
+ uint32_t c;
+ bytes = 0;
+ c = z[0];
+ if (c >= 0xc0)
+ {
+ c = utf8Trans1[c - 0xc0];
+ int index = 1;
+ while (index < nKey && (z[index] & 0xc0) == 0x80)
+ {
+ c = (c << 6) + (0x3f & z[index]);
+ index++;
+ }
+ if (c < 0x80 || (c & 0xFFFFF800) == 0xD800 || (c & 0xFFFFFFFE) == 0xFFFE)
+ c = 0xFFFD;
+ bytes = static_cast<unsigned char>(index - 1);
+ }
+ return c;
+ }
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace tools */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/tools/Thread.h b/xbmc/addons/kodi-dev-kit/include/kodi/tools/Thread.h
new file mode 100644
index 0000000..0510849
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/tools/Thread.h
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+#include "../General.h"
+
+#include <chrono>
+#include <condition_variable>
+#include <future>
+#include <mutex>
+#include <thread>
+
+namespace kodi
+{
+namespace tools
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_tools_CThread class CThread
+/// @ingroup cpp_kodi_tools
+/// @brief **Helper class to represent threads of execution**\n
+/// An execution thread is a sequence of instructions that can run concurrently
+/// with other such sequences in multithreaded environments while sharing the
+/// same address space.
+///
+/// Is intended to reduce any code work of C++ on addons and to have them faster
+/// to use.
+///
+/// His code uses the support of platform-independent thread system introduced
+/// with C++11.
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/tools/Thread.h>
+/// #include <kodi/AddonBase.h>
+///
+/// class ATTR_DLL_LOCAL CTestAddon
+/// : public kodi::addon::CAddonBase,
+/// public kodi::tools::CThread
+/// {
+/// public:
+/// CTestAddon() = default;
+///
+/// ADDON_STATUS Create() override;
+///
+/// void Process() override;
+/// };
+///
+/// ADDON_STATUS CTestAddon::Create()
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Starting thread");
+/// CreateThread();
+///
+/// Sleep(4000);
+///
+/// kodi::Log(ADDON_LOG_INFO, "Stopping thread");
+/// // This added as example and also becomes stopped by class destructor
+/// StopThread();
+///
+/// return ADDON_STATUS_OK;
+/// }
+///
+/// void CTestAddon::Process()
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Thread started");
+///
+/// while (!m_threadStop)
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Hello World");
+/// Sleep(1000);
+/// }
+///
+/// kodi::Log(ADDON_LOG_INFO, "Thread ended");
+/// }
+///
+/// ADDONCREATOR(CTestAddon)
+/// ~~~~~~~~~~~~~
+///
+///@{
+class CThread
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Class constructor.
+ ///
+ CThread() : m_threadStop(false) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Class destructor.
+ ///
+ virtual ~CThread()
+ {
+ StopThread();
+ if (m_thread != nullptr)
+ {
+ m_thread->detach();
+ delete m_thread;
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Check auto delete is enabled on this thread class.
+ ///
+ /// @return true if auto delete is used, false otherwise
+ ///
+ bool IsAutoDelete() const { return m_autoDelete; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Check caller is on this running thread.
+ ///
+ /// @return true if called from thread inside the class, false if from another
+ /// thread
+ ///
+ bool IsCurrentThread() const { return m_threadId == std::this_thread::get_id(); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Check thread inside this class is running and active.
+ ///
+ /// @note This function should be used from outside and not within process to
+ /// check thread is active. Use use atomic bool @ref m_threadStop for this.
+ ///
+ /// @return true if running, false if not
+ ///
+ bool IsRunning() const
+ {
+ if (m_thread != nullptr)
+ {
+ // it's possible that the thread exited on it's own without a call to StopThread. If so then
+ // the promise should be fulfilled.
+ std::future_status stat = m_future.wait_for(std::chrono::milliseconds(0));
+ // a status of 'ready' means the future contains the value so the thread has exited
+ // since the thread can't exit without setting the future.
+ if (stat == std::future_status::ready) // this is an indication the thread has exited.
+ return false;
+ return true; // otherwise the thread is still active.
+ }
+ else
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Create a new thread defined by this class on child.
+ ///
+ /// This starts then @ref Process() where is available on the child by addon.
+ ///
+ /// @param[in] autoDelete To set thread to delete itself after end, default is
+ /// false
+ ///
+ void CreateThread(bool autoDelete = false)
+ {
+ if (m_thread != nullptr)
+ {
+ // if the thread exited on it's own, without a call to StopThread, then we can get here
+ // incorrectly. We should be able to determine this by checking the promise.
+ std::future_status stat = m_future.wait_for(std::chrono::milliseconds(0));
+ // a status of 'ready' means the future contains the value so the thread has exited
+ // since the thread can't exit without setting the future.
+ if (stat == std::future_status::ready) // this is an indication the thread has exited.
+ StopThread(true); // so let's just clean up
+ else
+ { // otherwise we have a problem.
+ kodi::Log(ADDON_LOG_FATAL, "%s - fatal error creating thread - old thread id not null",
+ __func__);
+ exit(1);
+ }
+ }
+
+ m_autoDelete = autoDelete;
+ m_threadStop = false;
+ m_startEvent.notify_all();
+ m_stopEvent.notify_all();
+
+ std::promise<bool> prom;
+ m_future = prom.get_future();
+
+ {
+ // The std::thread internals must be set prior to the lambda doing
+ // any work. This will cause the lambda to wait until m_thread
+ // is fully initialized. Interestingly, using a std::atomic doesn't
+ // have the appropriate memory barrier behavior to accomplish the
+ // same thing so a full system mutex needs to be used.
+ std::unique_lock<std::recursive_mutex> lock(m_threadMutex);
+ m_thread = new std::thread(
+ [](CThread* thread, std::promise<bool> promise) {
+ try
+ {
+ {
+ // Wait for the pThread->m_thread internals to be set. Otherwise we could
+ // get to a place where we're reading, say, the thread id inside this
+ // lambda's call stack prior to the thread that kicked off this lambda
+ // having it set. Once this lock is released, the CThread::Create function
+ // that kicked this off is done so everything should be set.
+ std::unique_lock<std::recursive_mutex> lock(thread->m_threadMutex);
+ }
+
+ thread->m_threadId = std::this_thread::get_id();
+ std::stringstream ss;
+ ss << thread->m_threadId;
+ std::string id = ss.str();
+ bool autodelete = thread->m_autoDelete;
+
+ kodi::Log(ADDON_LOG_DEBUG, "Thread %s start, auto delete: %s", id.c_str(),
+ (autodelete ? "true" : "false"));
+
+ thread->m_running = true;
+ thread->m_startEvent.notify_one();
+
+ thread->Process();
+
+ if (autodelete)
+ {
+ kodi::Log(ADDON_LOG_DEBUG, "Thread %s terminating (autodelete)", id.c_str());
+ delete thread;
+ thread = nullptr;
+ }
+ else
+ kodi::Log(ADDON_LOG_DEBUG, "Thread %s terminating", id.c_str());
+ }
+ catch (const std::exception& e)
+ {
+ kodi::Log(ADDON_LOG_DEBUG, "Thread Terminating with Exception: %s", e.what());
+ }
+ catch (...)
+ {
+ kodi::Log(ADDON_LOG_DEBUG, "Thread Terminating with Exception");
+ }
+
+ promise.set_value(true);
+ },
+ this, std::move(prom));
+
+ m_startEvent.wait(lock);
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Stop a running thread.
+ ///
+ /// @param[in] wait As true (default) to wait until thread is finished and
+ /// stopped, as false the function return directly and thread
+ /// becomes independently stopped.
+ ///
+ void StopThread(bool wait = true)
+ {
+ std::unique_lock<std::recursive_mutex> lock(m_threadMutex);
+
+ if (m_threadStop)
+ return;
+
+ if (m_thread && !m_running)
+ m_startEvent.wait(lock);
+ m_running = false;
+ m_threadStop = true;
+ m_stopEvent.notify_one();
+
+ std::thread* lthread = m_thread;
+ if (lthread != nullptr && wait && !IsCurrentThread())
+ {
+ lock.unlock();
+ if (lthread->joinable())
+ lthread->join();
+ delete m_thread;
+ m_thread = nullptr;
+ m_threadId = std::thread::id();
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Thread sleep with given amount of milliseconds.
+ ///
+ /// This makes a sleep in the thread with a given time value. If it is called
+ /// within the process itself, it is also checked whether the thread is
+ /// terminated and the sleep process is thereby interrupted.
+ ///
+ /// If the external point calls this, only a regular sleep is used, which runs
+ /// through completely.
+ ///
+ /// @param[in] milliseconds Time to sleep
+ ///
+ void Sleep(uint32_t milliseconds)
+ {
+ if (milliseconds > 10 && IsCurrentThread())
+ {
+ std::unique_lock<std::recursive_mutex> lock(m_threadMutex);
+ m_stopEvent.wait_for(lock, std::chrono::milliseconds(milliseconds));
+ }
+ else
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
+ }
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief The function returns when the thread execution has completed or
+ /// timing is reached in milliseconds beforehand
+ ///
+ /// This synchronizes the moment this function returns with the completion of
+ /// all operations on the thread.
+ ///
+ /// @param[in] milliseconds Time to wait for join
+ ///
+ bool Join(unsigned int milliseconds)
+ {
+ std::unique_lock<std::recursive_mutex> lock(m_threadMutex);
+ std::thread* lthread = m_thread;
+ if (lthread != nullptr)
+ {
+ if (IsCurrentThread())
+ return false;
+
+ {
+ m_threadMutex.unlock(); // don't hold the thread lock while we're waiting
+ std::future_status stat = m_future.wait_for(std::chrono::milliseconds(milliseconds));
+ if (stat != std::future_status::ready)
+ return false;
+ m_threadMutex.lock();
+ }
+
+ // it's possible it's already joined since we released the lock above.
+ if (lthread->joinable())
+ m_thread->join();
+ return true;
+ }
+ else
+ return false;
+ }
+ //----------------------------------------------------------------------------
+
+protected:
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief The function to be added by the addon as a child to carry out the
+ /// process thread.
+ ///
+ /// Use @ref m_threadStop to check about active of thread and want stopped from
+ /// external place.
+ ///
+ /// @note This function is necessary and must be implemented by the addon.
+ ///
+ virtual void Process() = 0;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CThread
+ /// @brief Atomic bool to indicate thread is active.
+ ///
+ /// This should be used in @ref Process() to check the activity of the thread and,
+ /// if true, to terminate the process.
+ ///
+ /// - <b>`false`</b>: Thread active and should be run
+ /// - <b>`true`</b>: Thread ends and should be stopped
+ ///
+ std::atomic<bool> m_threadStop;
+ //----------------------------------------------------------------------------
+
+private:
+ bool m_autoDelete = false;
+ bool m_running = false;
+ std::condition_variable_any m_stopEvent;
+ std::condition_variable_any m_startEvent;
+ std::recursive_mutex m_threadMutex;
+ std::thread::id m_threadId;
+ std::thread* m_thread = nullptr;
+ std::future<bool> m_future;
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace tools */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/tools/Timer.h b/xbmc/addons/kodi-dev-kit/include/kodi/tools/Timer.h
new file mode 100644
index 0000000..3214e67
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/tools/Timer.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2005-2020 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+#include "Thread.h"
+
+#include <functional>
+
+namespace kodi
+{
+namespace tools
+{
+
+//==============================================================================
+/// @defgroup cpp_kodi_tools_CTimer class CTimer
+/// @ingroup cpp_kodi_tools
+/// @brief **Time interval management**\n
+/// Class which enables a time interval to be called up by a given function or
+/// class by means of a thread.
+///
+/// His code uses the support of platform-independent thread system introduced
+/// with C++11.
+///
+///
+/// ----------------------------------------------------------------------------
+///
+/// **Example:**
+/// ~~~~~~~~~~~~~{.cpp}
+/// #include <kodi/tools/Timer.h>
+///
+/// class ATTR_DLL_LOCAL CExample
+/// {
+/// public:
+/// CExample() : m_timer([this](){TimerCall();})
+/// {
+/// m_timer.Start(5000, true); // let call continuously all 5 seconds
+/// }
+///
+/// void TimerCall()
+/// {
+/// fprintf(stderr, "Hello World\n");
+/// }
+///
+/// private:
+/// kodi::tools::CTimer m_timer;
+/// };
+/// ~~~~~~~~~~~~~
+///
+///@{
+class CTimer : protected CThread
+{
+public:
+ class ITimerCallback;
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Class constructor to pass individual other class as callback.
+ ///
+ /// @param[in] callback Child class of parent @ref ITimerCallback with
+ /// implemented function @ref ITimerCallback::OnTimeout().
+ ///
+ explicit CTimer(kodi::tools::CTimer::ITimerCallback* callback)
+ : CTimer(std::bind(&ITimerCallback::OnTimeout, callback))
+ {
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Class constructor to pass individual function as callback.
+ ///
+ /// @param[in] callback Function to pass as callback about timeout.
+ ///
+ /// **Callback function style:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// void TimerCallback()
+ /// {
+ /// }
+ /// ~~~~~~~~~~~~~
+ explicit CTimer(std::function<void()> const& callback) : m_callback(callback) {}
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Class destructor.
+ ///
+ ~CTimer() override { Stop(true); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Start the timer by given time in milliseconds to make his call
+ /// by arrive of them.
+ ///
+ /// If interval is activated, it calls the associated callback function
+ /// continuously in the given interval.
+ ///
+ /// @param[in] timeout Timeout in milliseconds
+ /// @param[in] interval [opt] To run continuously if true, false only one time
+ /// and default
+ /// @return True if successfully done, false if not (callback missing,
+ /// timeout = 0 or was already running.
+ ///
+ bool Start(uint64_t timeout, bool interval = false)
+ {
+ using namespace std::chrono;
+
+ if (m_callback == nullptr || timeout == 0 || IsRunning())
+ return false;
+
+ m_timeout = milliseconds(timeout);
+ m_interval = interval;
+
+ CreateThread();
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Stop the timer if it is active.
+ ///
+ /// @param[in] wait [opt] Wait until timer is stopped, false is default and
+ /// call unblocked
+ /// @return True if timer was active and was stopped, false if already was
+ /// stopped.
+ ///
+ bool Stop(bool wait = false)
+ {
+ if (!IsRunning())
+ return false;
+
+ m_threadStop = true;
+ m_eventTimeout.notify_all();
+ StopThread(wait);
+
+ return true;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Restart timer complete by stop and restart his thread again.
+ ///
+ /// @note Restart only possible as long the timer was running and not done his
+ /// work.
+ ///
+ /// @return True if start was successfully done, on error, or if was already
+ /// finished returned as false
+ ///
+ bool Restart()
+ {
+ using namespace std::chrono;
+
+ if (!IsRunning())
+ return false;
+
+ Stop(true);
+ return Start(duration_cast<milliseconds>(m_timeout).count(), m_interval);
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Restart the timer with new timeout without touch of his thread.
+ ///
+ /// @param[in] timeout Time as milliseconds to wait for next call
+ ///
+ void RestartAsync(uint64_t timeout)
+ {
+ using namespace std::chrono;
+
+ m_timeout = milliseconds(timeout);
+ const auto now = system_clock::now();
+ m_endTime = now.time_since_epoch() + m_timeout;
+ m_eventTimeout.notify_all();
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Check timer is still active to wait for next call.
+ ///
+ /// @return True if active, false if all his work done and no more running
+ ///
+ bool IsRunning() const { return CThread::IsRunning(); }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Get elapsed time as floating point of timer as seconds.
+ ///
+ /// @return Elapsed time
+ ///
+ float GetElapsedSeconds() const { return GetElapsedMilliseconds() / 1000.0f; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief Get elapsed time as floating point of timer as milliseconds.
+ ///
+ /// @return Elapsed time
+ ///
+ float GetElapsedMilliseconds() const
+ {
+ using namespace std::chrono;
+
+ if (!IsRunning())
+ return 0.0f;
+
+ const auto now = system_clock::now();
+ return static_cast<float>(duration_cast<milliseconds>(now.time_since_epoch() - (m_endTime - m_timeout)).count());
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @defgroup cpp_kodi_tools_CTimer_CB class ITimerCallback
+ /// @ingroup cpp_kodi_tools_CTimer
+ /// @brief **Callback class of timer**\n
+ /// To give on constructor by @ref CTimer(kodi::tools::CTimer::ITimerCallback* callback)
+ ///
+ class ITimerCallback
+ {
+ public:
+ //==========================================================================
+ /// @ingroup cpp_kodi_tools_CTimer_CB
+ /// @brief Class destructor.
+ ///
+ virtual ~ITimerCallback() = default;
+ //--------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @ingroup cpp_kodi_tools_CTimer_CB
+ /// @brief Callback function to implement if constructor @ref CTimer(kodi::tools::CTimer::ITimerCallback* callback)
+ /// is used and this as parent on related class
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.cpp}
+ /// #include <kodi/tools/Timer.h>
+ ///
+ /// class CExample : public kodi::tools::CTimer,
+ /// private kodi::tools::CTimer::ITimerCallback
+ /// {
+ /// public:
+ /// CExample() : kodi::tools::CTimer(this)
+ /// {
+ /// }
+ ///
+ /// void OnTimeout() override
+ /// {
+ /// // Some work
+ /// }
+ /// };
+ ///
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual void OnTimeout() = 0;
+ //--------------------------------------------------------------------------
+ };
+ //----------------------------------------------------------------------------
+
+protected:
+ void Process() override
+ {
+ using namespace std::chrono;
+
+ while (!m_threadStop)
+ {
+ auto currentTime = system_clock::now();
+ m_endTime = currentTime.time_since_epoch() + m_timeout;
+
+ // wait the necessary time
+ std::mutex mutex;
+ std::unique_lock<std::mutex> lock(mutex);
+ const auto waitTime = duration_cast<milliseconds>(m_endTime - currentTime.time_since_epoch());
+ if (m_eventTimeout.wait_for(lock, waitTime) == std::cv_status::timeout)
+ {
+ currentTime = system_clock::now();
+ if (m_endTime.count() <= currentTime.time_since_epoch().count())
+ {
+ // execute OnTimeout() callback
+ m_callback();
+
+ // continue if this is an interval timer, or if it was restarted during callback
+ if (!m_interval && m_endTime.count() <= currentTime.time_since_epoch().count())
+ break;
+ }
+ }
+ }
+ }
+
+private:
+ bool m_interval = false;
+ std::function<void()> m_callback;
+ std::chrono::system_clock::duration m_timeout;
+ std::chrono::system_clock::duration m_endTime;
+ std::condition_variable_any m_eventTimeout;
+};
+///@}
+//------------------------------------------------------------------------------
+
+} /* namespace tools */
+} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/versions.h b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
new file mode 100644
index 0000000..c7f11c6
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2016-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.
+ */
+
+#pragma once
+
+#ifndef KODI_VERSIONS_H
+#define KODI_VERSIONS_H
+
+#include <string.h>
+
+#define STR_HELPER(x) #x
+#define STR(x) STR_HELPER(x)
+
+/*
+ *------------------------------------------------------------------------------
+ * Some parts on headers are only be used for Kodi itself and internally (not
+ * for add-on development).
+ *
+ * For this reason also no doxygen part with "///" defined there.
+ * -----------------------------------------------------------------------------
+ */
+
+/*
+ * Versions of all add-on globals and instances are defined below.
+ *
+ * This is added here and not in related header to prevent not
+ * needed includes during compile. Also have it here a better
+ * overview.
+ */
+
+// Ignore clang here, as this must be good in overview and as the main reason,
+// because cmake uses this area in this form to perform its addon dependency
+// check.
+// clang-format off
+#define ADDON_GLOBAL_VERSION_MAIN "2.0.2"
+#define ADDON_GLOBAL_VERSION_MAIN_MIN "2.0.0"
+#define ADDON_GLOBAL_VERSION_MAIN_XML_ID "kodi.binary.global.main"
+#define ADDON_GLOBAL_VERSION_MAIN_DEPENDS "AddonBase.h" \
+ "addon-instance/" \
+ "c-api/addon_base.h"
+
+#define ADDON_GLOBAL_VERSION_GENERAL "1.0.5"
+#define ADDON_GLOBAL_VERSION_GENERAL_MIN "1.0.4"
+#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.15.0"
+#define ADDON_GLOBAL_VERSION_GUI_MIN "5.15.0"
+#define ADDON_GLOBAL_VERSION_GUI_XML_ID "kodi.binary.global.gui"
+#define ADDON_GLOBAL_VERSION_GUI_DEPENDS "c-api/gui/input/action_ids.h" \
+ "c-api/gui/" \
+ "gui/"
+
+#define ADDON_GLOBAL_VERSION_AUDIOENGINE "1.1.1"
+#define ADDON_GLOBAL_VERSION_AUDIOENGINE_MIN "1.1.0"
+#define ADDON_GLOBAL_VERSION_AUDIOENGINE_XML_ID "kodi.binary.global.audioengine"
+#define ADDON_GLOBAL_VERSION_AUDIOENGINE_DEPENDS "AudioEngine.h" \
+ "c-api/audio_engine.h"
+
+#define ADDON_GLOBAL_VERSION_FILESYSTEM "1.1.8"
+#define ADDON_GLOBAL_VERSION_FILESYSTEM_MIN "1.1.7"
+#define ADDON_GLOBAL_VERSION_FILESYSTEM_XML_ID "kodi.binary.global.filesystem"
+#define ADDON_GLOBAL_VERSION_FILESYSTEM_DEPENDS "Filesystem.h" \
+ "c-api/filesystem.h" \
+ "gui/gl/Shader.h" \
+ "tools/DllHelper.h"
+
+#define ADDON_GLOBAL_VERSION_NETWORK "1.0.4"
+#define ADDON_GLOBAL_VERSION_NETWORK_MIN "1.0.0"
+#define ADDON_GLOBAL_VERSION_NETWORK_XML_ID "kodi.binary.global.network"
+#define ADDON_GLOBAL_VERSION_NETWORK_DEPENDS "Network.h" \
+ "c-api/network.h"
+
+#define ADDON_GLOBAL_VERSION_TOOLS "1.0.4"
+#define ADDON_GLOBAL_VERSION_TOOLS_MIN "1.0.0"
+#define ADDON_GLOBAL_VERSION_TOOLS_XML_ID "kodi.binary.global.tools"
+#define ADDON_GLOBAL_VERSION_TOOLS_DEPENDS "tools/DllHelper.h" \
+ "tools/EndTime.h" \
+ "tools/StringUtils.h" \
+ "tools/Thread.h" \
+ "tools/Timer.h"
+
+#define ADDON_INSTANCE_VERSION_AUDIODECODER "4.0.0"
+#define ADDON_INSTANCE_VERSION_AUDIODECODER_MIN "4.0.0"
+#define ADDON_INSTANCE_VERSION_AUDIODECODER_XML_ID "kodi.binary.instance.audiodecoder"
+#define ADDON_INSTANCE_VERSION_AUDIODECODER_DEPENDS "c-api/addon-instance/audiodecoder.h" \
+ "addon-instance/AudioDecoder.h"
+
+#define ADDON_INSTANCE_VERSION_AUDIOENCODER "3.0.0"
+#define ADDON_INSTANCE_VERSION_AUDIOENCODER_MIN "3.0.0"
+#define ADDON_INSTANCE_VERSION_AUDIOENCODER_XML_ID "kodi.binary.instance.audioencoder"
+#define ADDON_INSTANCE_VERSION_AUDIOENCODER_DEPENDS "c-api/addon-instance/audioencoder.h" \
+ "addon-instance/AudioEncoder.h"
+
+#define ADDON_INSTANCE_VERSION_GAME "3.0.0"
+#define ADDON_INSTANCE_VERSION_GAME_MIN "3.0.0"
+#define ADDON_INSTANCE_VERSION_GAME_XML_ID "kodi.binary.instance.game"
+#define ADDON_INSTANCE_VERSION_GAME_DEPENDS "addon-instance/Game.h"
+
+#define ADDON_INSTANCE_VERSION_IMAGEDECODER "3.0.1"
+#define ADDON_INSTANCE_VERSION_IMAGEDECODER_MIN "3.0.0"
+#define ADDON_INSTANCE_VERSION_IMAGEDECODER_XML_ID "kodi.binary.instance.imagedecoder"
+#define ADDON_INSTANCE_VERSION_IMAGEDECODER_DEPENDS "c-api/addon-instance/imagedecoder.h" \
+ "addon-instance/ImageDecoder.h"
+
+#define ADDON_INSTANCE_VERSION_INPUTSTREAM "3.2.0"
+#define ADDON_INSTANCE_VERSION_INPUTSTREAM_MIN "3.2.0"
+#define ADDON_INSTANCE_VERSION_INPUTSTREAM_XML_ID "kodi.binary.instance.inputstream"
+#define ADDON_INSTANCE_VERSION_INPUTSTREAM_DEPENDS "c-api/addon-instance/inputstream.h" \
+ "c-api/addon-instance/inputstream/demux_packet.h" \
+ "c-api/addon-instance/inputstream/stream_codec.h" \
+ "c-api/addon-instance/inputstream/stream_constants.h" \
+ "c-api/addon-instance/inputstream/stream_crypto.h" \
+ "c-api/addon-instance/inputstream/timing_constants.h" \
+ "addon-instance/Inputstream.h" \
+ "addon-instance/inputstream/DemuxPacket.h" \
+ "addon-instance/inputstream/StreamCodec.h" \
+ "addon-instance/inputstream/StreamConstants.h" \
+ "addon-instance/inputstream/StreamCrypto.h" \
+ "addon-instance/inputstream/TimingConstants.h"
+
+#define ADDON_INSTANCE_VERSION_PERIPHERAL "2.0.0"
+#define ADDON_INSTANCE_VERSION_PERIPHERAL_MIN "2.0.0"
+#define ADDON_INSTANCE_VERSION_PERIPHERAL_XML_ID "kodi.binary.instance.peripheral"
+#define ADDON_INSTANCE_VERSION_PERIPHERAL_DEPENDS "addon-instance/Peripheral.h" \
+ "addon-instance/PeripheralUtils.h"
+
+#define ADDON_INSTANCE_VERSION_PVR "8.2.0"
+#define ADDON_INSTANCE_VERSION_PVR_MIN "8.2.0"
+#define ADDON_INSTANCE_VERSION_PVR_XML_ID "kodi.binary.instance.pvr"
+#define ADDON_INSTANCE_VERSION_PVR_DEPENDS "c-api/addon-instance/pvr.h" \
+ "c-api/addon-instance/pvr/pvr_providers.h" \
+ "c-api/addon-instance/pvr/pvr_channel_groups.h" \
+ "c-api/addon-instance/pvr/pvr_channels.h" \
+ "c-api/addon-instance/pvr/pvr_defines.h" \
+ "c-api/addon-instance/pvr/pvr_edl.h" \
+ "c-api/addon-instance/pvr/pvr_epg.h" \
+ "c-api/addon-instance/pvr/pvr_general.h" \
+ "c-api/addon-instance/pvr/pvr_menu_hook.h" \
+ "c-api/addon-instance/pvr/pvr_recordings.h" \
+ "c-api/addon-instance/pvr/pvr_stream.h" \
+ "c-api/addon-instance/pvr/pvr_timers.h" \
+ "addon-instance/PVR.h" \
+ "addon-instance/pvr/ChannelGroups.h" \
+ "addon-instance/pvr/Channels.h" \
+ "addon-instance/pvr/EDL.h" \
+ "addon-instance/pvr/EPG.h" \
+ "addon-instance/pvr/General.h" \
+ "addon-instance/pvr/MenuHook.h" \
+ "addon-instance/pvr/Recordings.h" \
+ "addon-instance/pvr/Stream.h" \
+ "addon-instance/pvr/Timers.h"
+
+#define ADDON_INSTANCE_VERSION_SCREENSAVER "2.2.0"
+#define ADDON_INSTANCE_VERSION_SCREENSAVER_MIN "2.2.0"
+#define ADDON_INSTANCE_VERSION_SCREENSAVER_XML_ID "kodi.binary.instance.screensaver"
+#define ADDON_INSTANCE_VERSION_SCREENSAVER_DEPENDS "c-api/addon-instance/screensaver.h" \
+ "addon-instance/Screensaver.h"
+
+#define ADDON_INSTANCE_VERSION_VFS "3.0.1"
+#define ADDON_INSTANCE_VERSION_VFS_MIN "3.0.1"
+#define ADDON_INSTANCE_VERSION_VFS_XML_ID "kodi.binary.instance.vfs"
+#define ADDON_INSTANCE_VERSION_VFS_DEPENDS "c-api/addon-instance/vfs.h" \
+ "addon-instance/VFS.h"
+
+#define ADDON_INSTANCE_VERSION_VISUALIZATION "4.0.0"
+#define ADDON_INSTANCE_VERSION_VISUALIZATION_MIN "4.0.0"
+#define ADDON_INSTANCE_VERSION_VISUALIZATION_XML_ID "kodi.binary.instance.visualization"
+#define ADDON_INSTANCE_VERSION_VISUALIZATION_DEPENDS "addon-instance/Visualization.h" \
+ "c-api/addon-instance/visualization.h"
+
+#define ADDON_INSTANCE_VERSION_VIDEOCODEC "2.0.3"
+#define ADDON_INSTANCE_VERSION_VIDEOCODEC_MIN "2.0.1"
+#define ADDON_INSTANCE_VERSION_VIDEOCODEC_XML_ID "kodi.binary.instance.videocodec"
+#define ADDON_INSTANCE_VERSION_VIDEOCODEC_DEPENDS "c-api/addon-instance/video_codec.h" \
+ "c-api/addon-instance/inputstream/stream_codec.h" \
+ "c-api/addon-instance/inputstream/stream_crypto.h" \
+ "addon-instance/VideoCodec.h" \
+ "addon-instance/inputstream/StreamCodec.h" \
+ "addon-instance/inputstream/StreamCrypto.h" \
+// clang-format on
+
+//==============================================================================
+/// @ingroup cpp_kodi_addon_addonbase_Defs
+/// @defgroup cpp_kodi_addon_addonbase_Defs_ADDON_TYPE enum ADDON_TYPE
+/// **The currently available instance types for Kodi add-ons**\n
+/// This identifies the associated API part on the interface in Kodi and in the
+/// addon.
+///
+/// \internal
+/// @note For add of new types take a new number on end. To change
+/// existing numbers can be make problems on already compiled add-ons.
+/// \endinternal
+///
+///@{
+typedef enum ADDON_TYPE
+{
+ /* addon global parts */
+ ADDON_GLOBAL_MAIN = 0,
+ ADDON_GLOBAL_GUI = 1,
+ ADDON_GLOBAL_AUDIOENGINE = 2,
+ ADDON_GLOBAL_GENERAL = 3,
+ ADDON_GLOBAL_NETWORK = 4,
+ ADDON_GLOBAL_FILESYSTEM = 5,
+ ADDON_GLOBAL_TOOLS = 6,
+ // Last used global id, used in loops to check versions.
+ // Need to change if new global type becomes added!
+ ADDON_GLOBAL_MAX = 6,
+
+ /* addon type instances */
+
+ /// Audio decoder instance, see @ref cpp_kodi_addon_audiodecoder "kodi::addon::CInstanceAudioDecoder"
+ ADDON_INSTANCE_AUDIODECODER = 102,
+
+ /// Audio encoder instance, see @ref cpp_kodi_addon_audioencoder "kodi::addon::CInstanceAudioEncoder"
+ ADDON_INSTANCE_AUDIOENCODER = 103,
+
+ /// Game instance, see @ref cpp_kodi_addon_game "kodi::addon::CInstanceGame"
+ ADDON_INSTANCE_GAME = 104,
+
+ /// Input stream instance, see @ref cpp_kodi_addon_inputstream "kodi::addon::CInstanceInputStream"
+ ADDON_INSTANCE_INPUTSTREAM = 105,
+
+ /// Peripheral instance, see @ref cpp_kodi_addon_peripheral "kodi::addon::CInstancePeripheral"
+ ADDON_INSTANCE_PERIPHERAL = 106,
+
+ /// Game instance, see @ref cpp_kodi_addon_pvr "kodi::addon::CInstancePVRClient"
+ ADDON_INSTANCE_PVR = 107,
+
+ /// PVR client instance, see @ref cpp_kodi_addon_screensaver "kodi::addon::CInstanceScreensaver"
+ ADDON_INSTANCE_SCREENSAVER = 108,
+
+ /// Music visualization instance, see @ref cpp_kodi_addon_visualization "kodi::addon::CInstanceVisualization"
+ ADDON_INSTANCE_VISUALIZATION = 109,
+
+ /// Virtual Filesystem (VFS) instance, see @ref cpp_kodi_addon_vfs "kodi::addon::CInstanceVFS"
+ ADDON_INSTANCE_VFS = 110,
+
+ /// Image Decoder instance, see @ref cpp_kodi_addon_imagedecoder "kodi::addon::CInstanceImageDecoder"
+ ADDON_INSTANCE_IMAGEDECODER = 111,
+
+ /// Video Decoder instance, see @ref cpp_kodi_addon_videocodec "kodi::addon::CInstanceVideoCodec"
+ ADDON_INSTANCE_VIDEOCODEC = 112,
+} ADDON_TYPE;
+///@}
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+namespace kodi {
+namespace addon {
+#endif
+
+///
+/// This is used from Kodi to get the active version of add-on parts.
+/// It is compiled in add-on and also in Kodi itself, with this can be Kodi
+/// compare the version from him with them on add-on.
+///
+/// @param[in] type The with 'enum ADDON_TYPE' type to ask
+/// @return version The current version of asked type
+///
+inline const char* GetTypeVersion(int type)
+{
+ /*
+ * #ifdef's below becomes set by cmake, no set by hand needed.
+ */
+ switch (type)
+ {
+ /* addon global parts */
+ case ADDON_GLOBAL_MAIN:
+ return ADDON_GLOBAL_VERSION_MAIN;
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_GLOBAL_VERSION_GENERAL_USED)
+ case ADDON_GLOBAL_GENERAL:
+ return ADDON_GLOBAL_VERSION_GENERAL;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_GLOBAL_VERSION_GUI_USED)
+ case ADDON_GLOBAL_GUI:
+ return ADDON_GLOBAL_VERSION_GUI;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_GLOBAL_VERSION_AUDIOENGINE_USED)
+ case ADDON_GLOBAL_AUDIOENGINE:
+ return ADDON_GLOBAL_VERSION_AUDIOENGINE;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_GLOBAL_VERSION_FILESYSTEM_USED)
+ case ADDON_GLOBAL_FILESYSTEM:
+ return ADDON_GLOBAL_VERSION_FILESYSTEM;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_GLOBAL_VERSION_NETWORK_USED)
+ case ADDON_GLOBAL_NETWORK:
+ return ADDON_GLOBAL_VERSION_NETWORK;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_GLOBAL_VERSION_TOOLS_USED)
+ case ADDON_GLOBAL_TOOLS:
+ return ADDON_GLOBAL_VERSION_TOOLS;
+#endif
+
+ /* addon type instances */
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_AUDIODECODER_USED)
+ case ADDON_INSTANCE_AUDIODECODER:
+ return ADDON_INSTANCE_VERSION_AUDIODECODER;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_AUDIOENCODER_USED)
+ case ADDON_INSTANCE_AUDIOENCODER:
+ return ADDON_INSTANCE_VERSION_AUDIOENCODER;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_GAME_USED)
+ case ADDON_INSTANCE_GAME:
+ return ADDON_INSTANCE_VERSION_GAME;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_IMAGEDECODER_USED)
+ case ADDON_INSTANCE_IMAGEDECODER:
+ return ADDON_INSTANCE_VERSION_IMAGEDECODER;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_INPUTSTREAM_USED)
+ case ADDON_INSTANCE_INPUTSTREAM:
+ return ADDON_INSTANCE_VERSION_INPUTSTREAM;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_PERIPHERAL_USED)
+ case ADDON_INSTANCE_PERIPHERAL:
+ return ADDON_INSTANCE_VERSION_PERIPHERAL;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_PVR_USED)
+ case ADDON_INSTANCE_PVR:
+ return ADDON_INSTANCE_VERSION_PVR;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_SCREENSAVER_USED)
+ case ADDON_INSTANCE_SCREENSAVER:
+ return ADDON_INSTANCE_VERSION_SCREENSAVER;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_VFS_USED)
+ case ADDON_INSTANCE_VFS:
+ return ADDON_INSTANCE_VERSION_VFS;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_VISUALIZATION_USED)
+ case ADDON_INSTANCE_VISUALIZATION:
+ return ADDON_INSTANCE_VERSION_VISUALIZATION;
+#endif
+#if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_VIDEOCODEC_USED)
+ case ADDON_INSTANCE_VIDEOCODEC:
+ return ADDON_INSTANCE_VERSION_VIDEOCODEC;
+#endif
+ }
+ return "0.0.0";
+}
+
+///
+/// This is used from Kodi to get the minimum supported version of add-on parts.
+/// It is compiled in add-on and also in Kodi itself, with this can be Kodi
+/// compare the version from him with them on add-on.
+///
+/// @param[in] type The with 'enum ADDON_TYPE' type to ask
+/// @return version The minimum version of asked type
+///
+inline const char* GetTypeMinVersion(int type)
+{
+ switch (type)
+ {
+ /* addon global parts */
+ case ADDON_GLOBAL_MAIN:
+ return ADDON_GLOBAL_VERSION_MAIN_MIN;
+ case ADDON_GLOBAL_GUI:
+ return ADDON_GLOBAL_VERSION_GUI_MIN;
+ case ADDON_GLOBAL_GENERAL:
+ return ADDON_GLOBAL_VERSION_GENERAL_MIN;
+ case ADDON_GLOBAL_AUDIOENGINE:
+ return ADDON_GLOBAL_VERSION_AUDIOENGINE_MIN;
+ case ADDON_GLOBAL_FILESYSTEM:
+ return ADDON_GLOBAL_VERSION_FILESYSTEM_MIN;
+ case ADDON_GLOBAL_NETWORK:
+ return ADDON_GLOBAL_VERSION_NETWORK_MIN;
+ case ADDON_GLOBAL_TOOLS:
+ return ADDON_GLOBAL_VERSION_TOOLS_MIN;
+
+ /* addon type instances */
+ case ADDON_INSTANCE_AUDIODECODER:
+ return ADDON_INSTANCE_VERSION_AUDIODECODER_MIN;
+ case ADDON_INSTANCE_AUDIOENCODER:
+ return ADDON_INSTANCE_VERSION_AUDIOENCODER_MIN;
+ case ADDON_INSTANCE_GAME:
+ return ADDON_INSTANCE_VERSION_GAME_MIN;
+ case ADDON_INSTANCE_IMAGEDECODER:
+ return ADDON_INSTANCE_VERSION_IMAGEDECODER_MIN;
+ case ADDON_INSTANCE_INPUTSTREAM:
+ return ADDON_INSTANCE_VERSION_INPUTSTREAM_MIN;
+ case ADDON_INSTANCE_PERIPHERAL:
+ return ADDON_INSTANCE_VERSION_PERIPHERAL_MIN;
+ case ADDON_INSTANCE_PVR:
+ return ADDON_INSTANCE_VERSION_PVR_MIN;
+ case ADDON_INSTANCE_SCREENSAVER:
+ return ADDON_INSTANCE_VERSION_SCREENSAVER_MIN;
+ case ADDON_INSTANCE_VFS:
+ return ADDON_INSTANCE_VERSION_VFS_MIN;
+ case ADDON_INSTANCE_VISUALIZATION:
+ return ADDON_INSTANCE_VERSION_VISUALIZATION_MIN;
+ case ADDON_INSTANCE_VIDEOCODEC:
+ return ADDON_INSTANCE_VERSION_VIDEOCODEC_MIN;
+ }
+ return "0.0.0";
+}
+
+///
+/// Function used internally on add-on and in Kodi itself to get name
+/// about given type.
+///
+/// @param[in] type The with 'enum ADDON_TYPE' defined type to ask
+/// @return Name of the asked instance type
+///
+inline const char* GetTypeName(int type)
+{
+ switch (type)
+ {
+ /* addon global parts */
+ case ADDON_GLOBAL_MAIN:
+ return "Addon";
+ case ADDON_GLOBAL_GUI:
+ return "GUI";
+ case ADDON_GLOBAL_GENERAL:
+ return "General";
+ case ADDON_GLOBAL_AUDIOENGINE:
+ return "AudioEngine";
+ case ADDON_GLOBAL_FILESYSTEM:
+ return "Filesystem";
+ case ADDON_GLOBAL_NETWORK:
+ return "Network";
+ case ADDON_GLOBAL_TOOLS:
+ return "Tools";
+
+ /* addon type instances */
+ case ADDON_INSTANCE_AUDIODECODER:
+ return "AudioDecoder";
+ case ADDON_INSTANCE_AUDIOENCODER:
+ return "AudioEncoder";
+ case ADDON_INSTANCE_GAME:
+ return "Game";
+ case ADDON_INSTANCE_IMAGEDECODER:
+ return "ImageDecoder";
+ case ADDON_INSTANCE_INPUTSTREAM:
+ return "Inputstream";
+ case ADDON_INSTANCE_PERIPHERAL:
+ return "Peripheral";
+ case ADDON_INSTANCE_PVR:
+ return "PVR";
+ case ADDON_INSTANCE_SCREENSAVER:
+ return "ScreenSaver";
+ case ADDON_INSTANCE_VISUALIZATION:
+ return "Visualization";
+ case ADDON_INSTANCE_VIDEOCODEC:
+ return "VideoCodec";
+ }
+ return "unknown";
+}
+
+///
+/// Function used internally on add-on and in Kodi itself to get id number
+/// about given type name.
+///
+/// @param[in] name The type name string to ask
+/// @return Id number of the asked instance type
+///
+/// @warning String must be lower case here!
+///
+inline int GetTypeId(const char* name)
+{
+ if (name)
+ {
+ if (strcmp(name, "addon") == 0)
+ return ADDON_GLOBAL_MAIN;
+ else if (strcmp(name, "general") == 0)
+ return ADDON_GLOBAL_GENERAL;
+ else if (strcmp(name, "gui") == 0)
+ return ADDON_GLOBAL_GUI;
+ else if (strcmp(name, "audioengine") == 0)
+ return ADDON_GLOBAL_AUDIOENGINE;
+ else if (strcmp(name, "filesystem") == 0)
+ return ADDON_GLOBAL_FILESYSTEM;
+ else if (strcmp(name, "network") == 0)
+ return ADDON_GLOBAL_NETWORK;
+ else if (strcmp(name, "tools") == 0)
+ return ADDON_GLOBAL_TOOLS;
+ else if (strcmp(name, "audiodecoder") == 0)
+ return ADDON_INSTANCE_AUDIODECODER;
+ else if (strcmp(name, "audioencoder") == 0)
+ return ADDON_INSTANCE_AUDIOENCODER;
+ else if (strcmp(name, "game") == 0)
+ return ADDON_INSTANCE_GAME;
+ else if (strcmp(name, "imagedecoder") == 0)
+ return ADDON_INSTANCE_IMAGEDECODER;
+ else if (strcmp(name, "inputstream") == 0)
+ return ADDON_INSTANCE_INPUTSTREAM;
+ else if (strcmp(name, "peripheral") == 0)
+ return ADDON_INSTANCE_PERIPHERAL;
+ else if (strcmp(name, "pvr") == 0)
+ return ADDON_INSTANCE_PVR;
+ else if (strcmp(name, "screensaver") == 0)
+ return ADDON_INSTANCE_SCREENSAVER;
+ else if (strcmp(name, "vfs") == 0)
+ return ADDON_INSTANCE_VFS;
+ else if (strcmp(name, "visualization") == 0)
+ return ADDON_INSTANCE_VISUALIZATION;
+ else if (strcmp(name, "videocodec") == 0)
+ return ADDON_INSTANCE_VIDEOCODEC;
+ }
+ return -1;
+}
+
+#ifdef __cplusplus
+} /* namespace addon */
+} /* namespace kodi */
+} /* extern "C" */
+#endif
+
+#endif /* !KODI_VERSIONS_H */
diff --git a/xbmc/addons/kodi-dev-kit/tools/code-generator/code_generator.py b/xbmc/addons/kodi-dev-kit/tools/code-generator/code_generator.py
new file mode 100755
index 0000000..06cf810
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/tools/code-generator/code_generator.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2021 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.
+
+KODI_DIR = "../../../../../"
+DEVKIT_DIR = "xbmc/addons/kodi-dev-kit"
+
+# Global includes
+from optparse import OptionParser
+
+# Own includes
+from src.commitChanges import *
+from src.generateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt import *
+from src.generateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_allfiles import *
+from src.helper_Log import *
+
+# ===============================================================================
+def GenerateCMakeParts(options):
+ Log.PrintGroupStart("Generate cmake parts")
+
+ # Generate Kodi's cmake system related include files to find related parts
+ GenerateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_all_files(options)
+ GenerateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt(options)
+
+
+# ===============================================================================
+if __name__ == "__main__":
+ # parse command-line options
+ disc = """\
+This utility autogenerate the interface between Kodi and addon.
+It is currently still in the initial phase and will be expanded in the future.
+"""
+ parser = OptionParser(description=disc)
+ parser.add_option(
+ "-f",
+ "--force",
+ action="store_true",
+ dest="force",
+ default=False,
+ help="Force the generation of auto code",
+ )
+ parser.add_option(
+ "-d",
+ "--debug",
+ action="store_true",
+ dest="debug",
+ default=False,
+ help="Add debug identifiers to generated files",
+ )
+ parser.add_option(
+ "-c",
+ "--commit",
+ action="store_true",
+ dest="commit",
+ default=False,
+ help="Create automatic a git commit about API changes (WARNING: No hand edits should be present before!)",
+ )
+ (options, args) = parser.parse_args()
+
+ Log.Init(options)
+ Log.PrintMainStart(options)
+
+ ##----------------------------------------------------------------------------
+ # CMake generation
+ GenerateCMakeParts(options)
+
+ ##----------------------------------------------------------------------------
+ # Commit GIT changes generation (only makes work if '-c' option is used)
+ if options.commit:
+ Log.PrintGroupStart("Git update")
+ CommitChanges(options)
diff --git a/xbmc/addons/kodi-dev-kit/tools/code-generator/src/commitChanges.py b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/commitChanges.py
new file mode 100644
index 0000000..896cca5
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/commitChanges.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2021 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.
+
+# Own includes
+from code_generator import DEVKIT_DIR, KODI_DIR
+from .generateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt import *
+from .generateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_allfiles import *
+from .helper_Log import *
+
+# Global includes
+import importlib, os, subprocess
+
+git_found = importlib.find_loader("git") is not None
+if git_found:
+ from git import Repo
+
+
+def CommitChanges(options):
+ """
+ Do a git commit of the automatically changed locations of the dev-kit.
+ """
+ if not options.commit:
+ return
+ if not git_found:
+ Log.PrintFatal(
+ 'Needed "GitPython" module not present! To make commits need them be installed.'
+ )
+ quit(1)
+
+ Log.PrintBegin("Perform GIT update check")
+ Log.PrintResult(Result.SEE_BELOW)
+
+ contains_devkit_change = False
+ contains_external_change = False
+ changes_list = []
+
+ # Hack place one to get also new added files
+ subprocess.run(["git", "add", "-A"], check=True, stdout=subprocess.PIPE).stdout
+
+ r = Repo(KODI_DIR)
+ for x in r.index.diff("HEAD"):
+ if GenerateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_all_files_RelatedCheck(
+ x.b_path
+ ):
+ Log.PrintBegin(" - Changed file {}".format(x.b_path))
+ contains_devkit_change = True
+ changes_list.append(x.b_path)
+ Log.PrintResult(Result.NEW if x.new_file else Result.UPDATE)
+ elif GenerateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt_RelatedCheck(
+ x.b_path
+ ):
+ Log.PrintBegin(" - Changed file {}".format(x.b_path))
+ contains_devkit_change = True
+ changes_list.append(x.b_path)
+ Log.PrintResult(Result.NEW if x.new_file else Result.UPDATE)
+ else:
+ Log.PrintBegin(" - Changed file {}".format(x.b_path))
+ Log.PrintFollow(" (Not auto update related)")
+ Log.PrintResult(Result.IGNORED)
+ contains_external_change = True
+
+ # Hack place two to reset about before
+ subprocess.run(["git", "reset", "HEAD"], check=True, stdout=subprocess.PIPE).stdout
+
+ Log.PrintBegin("Perform GIT commit")
+ if contains_devkit_change:
+ # Add changed or added files to git
+ for x in changes_list:
+ r.index.add(x)
+
+ commit_msg = (
+ "[auto][addons] devkit script update ({})\n"
+ "\n"
+ "This commit automatic generated by script '{}/tools/code-generator.py'.\n"
+ "\n"
+ "{}".format(
+ datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S"),
+ DEVKIT_DIR,
+ open(Log.log_file).read(),
+ )
+ )
+ r.index.commit(commit_msg)
+ Log.PrintFollow(" ( Commit SHA256: {})".format(str(r.head.reference.commit)))
+ Log.PrintResult(Result.OK)
+ else:
+ Log.PrintResult(Result.ALREADY_DONE)
diff --git a/xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt.py b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt.py
new file mode 100644
index 0000000..20ed447
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2021 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.
+
+# Own includes
+from code_generator import DEVKIT_DIR, KODI_DIR
+from .helper_Log import *
+
+# Global includes
+import glob, os, re
+
+
+def GenerateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt_RelatedCheck(filename):
+ """
+ This function is called by git update to be able to assign changed files to the dev kit.
+ """
+ return True if filename == "cmake/treedata/common/addon_dev_kit.txt" else False
+
+
+def GenerateCMake__CMAKE_TREEDATA_COMMON_addon_dev_kit_txt(options):
+ """
+ This function generate the "cmake/treedata/common/addon_dev_kit.txt"
+ by scan of related directories to use for addon interface build.
+ """
+ gen_file = "cmake/treedata/common/addon_dev_kit.txt"
+
+ Log.PrintBegin("Check for {}".format(gen_file))
+
+ scan_dir = "{}{}/include/kodi/**/CMakeLists.txt".format(KODI_DIR, DEVKIT_DIR)
+ parts = "# Auto generated {}.\n" "# See {}/tools/code-generator.py.\n\n".format(
+ gen_file, DEVKIT_DIR
+ )
+
+ for entry in glob.glob(scan_dir, recursive=True):
+ cmake_dir = entry.replace(KODI_DIR, "").replace("/CMakeLists.txt", "")
+ with open(entry) as search:
+ for line in search:
+ line = line.rstrip() # remove '\n' at end of line
+ m = re.search("^ *core_add_devkit_header\((.*)\)", line)
+ if m:
+ parts += "{} addons_kodi-dev-kit_include_{}\n".format(
+ cmake_dir, m.group(1)
+ )
+ break
+ file = "{}{}".format(KODI_DIR, gen_file)
+ present = os.path.isfile(file)
+ if not present or parts != open(file).read() or options.force:
+ with open(file, "w") as f:
+ f.write(parts)
+ Log.PrintResult(Result.NEW if not present else Result.UPDATE)
+ else:
+ Log.PrintResult(Result.ALREADY_DONE)
diff --git a/xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_allfiles.py b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_allfiles.py
new file mode 100644
index 0000000..c1000be
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/generateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_allfiles.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2021 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.
+
+# Own includes
+from code_generator import DEVKIT_DIR, KODI_DIR
+from .helper_Log import *
+
+# Global includes
+import glob, os, re
+
+
+def GenerateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_all_files_RelatedCheck(filename):
+ """
+ This function is called by git update to be able to assign changed files to the dev kit.
+ """
+ scan_dir = "{}{}/include/kodi/**/".format(KODI_DIR, DEVKIT_DIR)
+ dirs = sorted(glob.glob(scan_dir, recursive=True))
+ for dir in dirs:
+ source_dir = "{}CMakeLists.txt".format(dir.replace(KODI_DIR, ""))
+ if source_dir == filename:
+ return True
+
+ return False
+
+
+def GenerateCMake__XBMC_ADDONS_KODIDEVKIT_INCLUDE_KODI_all_files(options):
+ """
+ This function generate the "CMakeLists.txt" in xbmc/addons/kodi-dev-kit/include/kodi
+ and sub dirs by scan of available files
+ """
+ Log.PrintBegin(
+ "Generate CMakeLists.txt files in {}/include/kodi dirs".format(DEVKIT_DIR)
+ )
+ Log.PrintResult(Result.SEE_BELOW)
+
+ scan_dir = "{}{}/include/kodi/**/".format(KODI_DIR, DEVKIT_DIR)
+
+ found = False
+ dirs = sorted(glob.glob(scan_dir, recursive=True))
+ for dir in dirs:
+ source_dir = dir.replace(KODI_DIR, "")
+ Log.PrintBegin(" - Check {}CMakeLists.txt".format(source_dir))
+
+ # Scan for *.h
+ os_limits = []
+ header_configure = []
+ header_entry = []
+ src_parts = sorted(glob.glob("{}*.h*".format(dir), recursive=False))
+ for src_part in src_parts:
+ with open(src_part) as search:
+ for line in search:
+ line = line.rstrip() # remove '\n' at end of line
+ m = re.search("^\/\*---AUTO_GEN_PARSE<\$\$(.*):(.*)>---\*\/", line)
+ if m:
+ if m.group(1) == "CORE_SYSTEM_NAME":
+ if src_part.endswith(".in"):
+ Log.PrintResult(Result.FAILURE)
+ Log.PrintFatal(
+ 'File extensions with ".h.in" are currently not supported and require revision of Kodi\'s cmake system!'
+ )
+ exit(1)
+ """
+ NOTE: This code currently unused. About ".in" support need Kodi's cmake build system revised.
+ code = ''
+ for entry in m.group(2).split(","):
+ label = 'CORE_SYSTEM_NAME STREQUAL {}'.format(entry)
+ code += 'if({}'.format(label) if code == '' else ' OR\n {}'.format(label)
+ code += ')\n'
+ code += ' configure_file(${{CMAKE_SOURCE_DIR}}/{}\n'.format(src_part.replace(KODI_DIR, ''))
+ code += ' ${{CORE_BUILD_DIR}}/{} @ONLY)\n'.format(src_part.replace(KODI_DIR, '').replace('.in', ''))
+ code += 'endif()'
+ header_configure.append(code)
+ """
+ for entry in m.group(2).split(","):
+ entry = entry.strip()
+ if not entry in os_limits:
+ os_limits.append(entry)
+ header_entry.append(
+ "$<$<STREQUAL:${{CORE_SYSTEM_NAME}},{}>:{}>".format(
+ entry,
+ src_part.replace(dir, "").replace(".in", ""),
+ )
+ )
+ found = True
+ break
+ if not found:
+ header_entry.append(src_part.replace(dir, ""))
+ found = False
+
+ if len(os_limits) > 0:
+ Log.PrintFollow(
+ " (Contains limited OS header: {})".format(
+ ", ".join(map(str, os_limits))
+ )
+ )
+
+ cmake_cfg_text = (
+ "\n{}".format("".join("{}\n".format(entry) for entry in header_configure))
+ if len(header_configure) > 0
+ else ""
+ )
+ cmake_hdr_text = "set(HEADERS\n{})\n".format(
+ "".join(" {}\n".format(entry) for entry in header_entry)
+ )
+ cmake_part = (
+ source_dir[len(DEVKIT_DIR + "/include_") :].replace("/", "_").rstrip("_")
+ ) # Generate cmake sub part name
+
+ # Make final CMakeLists.txt
+ cmake_file = (
+ "# Auto generated CMakeLists.txt.\n"
+ "# See {}/tools/code-generator.py.\n"
+ "{}"
+ "\n"
+ "{}"
+ "\n"
+ "if(HEADERS)\n"
+ " core_add_devkit_header({})\n"
+ "endif()\n".format(DEVKIT_DIR, cmake_cfg_text, cmake_hdr_text, cmake_part)
+ )
+
+ file = "{}CMakeLists.txt".format(dir)
+ present = os.path.isfile(file)
+ if not present or cmake_file != open(file).read() or options.force:
+ with open(file, "w") as f:
+ f.write(cmake_file)
+ Log.PrintResult(Result.NEW if not present else Result.UPDATE)
+ else:
+ Log.PrintResult(Result.ALREADY_DONE)
diff --git a/xbmc/addons/kodi-dev-kit/tools/code-generator/src/helper_Log.py b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/helper_Log.py
new file mode 100644
index 0000000..6279afa
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/tools/code-generator/src/helper_Log.py
@@ -0,0 +1,201 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2021 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.
+
+from datetime import datetime
+import os
+
+
+class Result:
+ OK = 1
+ FAILURE = 2
+ UPDATE = 3
+ ALREADY_DONE = 4
+ NEW = 5
+ SEE_BELOW = 6
+ IGNORED = 7
+
+
+class Log:
+ log_file = "creation_log.txt"
+ current_cursor_pos = 0
+ terminal_columns = 120
+
+ # Class of different styles
+ class style:
+ BOLD = "\033[01m"
+ BLACK = "\033[30m"
+ RED = "\033[31m"
+ GREEN = "\033[32m"
+ YELLOW = "\033[33m"
+ BLUE = "\033[34m"
+ MAGENTA = "\033[35m"
+ CYAN = "\033[36m"
+ WHITE = "\033[37m"
+ UNDERLINE = "\033[4m"
+ RESET = "\033[0m"
+
+ def Init(options):
+ # Try to get terminal with, is optional and no matter if something fails
+ try:
+ columns, rows = os.get_terminal_size(0)
+ Log.terminal_columns = columns
+ except:
+ pass
+
+ if os.path.isfile(Log.log_file):
+ os.rename(Log.log_file, Log.log_file + ".old")
+
+ if options.debug:
+ print("DEBUG: Used command line options: {}".format(str(options)))
+
+ with open(Log.log_file, "w") as f:
+ f.write("Used call options: {}\n".format(str(options)))
+
+ def PrintMainStart(options):
+ print("┌{}┐".format("─" * (Log.terminal_columns - 2)))
+ text = "Auto generation of addon interface code"
+ print(
+ "│ {}{}{}{}{}│".format(
+ Log.style.BOLD,
+ Log.style.CYAN,
+ text,
+ Log.style.RESET,
+ " " * (Log.terminal_columns - len(text) - 3),
+ )
+ )
+ text = "Used options:"
+ print(
+ "│ {}{}{}{}{}{}│".format(
+ Log.style.BOLD,
+ Log.style.WHITE,
+ Log.style.UNDERLINE,
+ text,
+ Log.style.RESET,
+ " " * (Log.terminal_columns - len(text) - 3),
+ )
+ )
+ Log.__printUsedBooleanValueLine("force", options.force)
+ Log.__printUsedBooleanValueLine("debug", options.debug)
+ Log.__printUsedBooleanValueLine("commit", options.commit)
+ print("└{}┘".format("─" * (Log.terminal_columns - 2)))
+
+ def PrintGroupStart(text):
+ print("─" * Log.terminal_columns)
+ print(
+ "{}{} ...{}{}".format(
+ Log.style.CYAN,
+ text,
+ " " * (Log.terminal_columns - len(text) - 4),
+ Log.style.RESET,
+ )
+ )
+ with open(Log.log_file, "a") as f:
+ f.write("{}...\n".format(text))
+
+ def PrintBegin(text):
+ # datetime object containing current date and time
+ dt_string = datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S")
+ Log.current_cursor_pos = len(text) + len(dt_string) + 3
+
+ print(
+ "[{}{}{}] {}{}{}{}".format(
+ Log.style.MAGENTA,
+ dt_string,
+ Log.style.RESET,
+ Log.style.WHITE,
+ Log.style.BOLD,
+ text,
+ Log.style.RESET,
+ ),
+ end="",
+ )
+ with open(Log.log_file, "a") as f:
+ f.write("[{}] {}: ".format(dt_string, text))
+
+ def PrintFollow(text):
+ Log.current_cursor_pos += len(text)
+
+ print(Log.style.CYAN + text + Log.style.RESET, end="")
+ with open(Log.log_file, "a") as f:
+ f.write("{} ".format(text))
+
+ def PrintResult(result_type, result_text=None):
+ text = ""
+ color = Log.style.WHITE
+
+ if result_type == Result.OK:
+ text = "OK"
+ color = Log.style.GREEN
+ elif result_type == Result.NEW:
+ text = "Created new"
+ color = Log.style.CYAN
+ elif result_type == Result.FAILURE:
+ text = "Failed"
+ color = Log.style.RED
+ elif result_type == Result.UPDATE:
+ text = "Updated"
+ color = Log.style.YELLOW
+ elif result_type == Result.ALREADY_DONE:
+ text = "Present and up to date"
+ color = Log.style.GREEN
+ elif result_type == Result.SEE_BELOW:
+ text = "See below"
+ color = Log.style.BLUE
+ elif result_type == Result.IGNORED:
+ text = "Ignored"
+ color = Log.style.YELLOW
+
+ print(
+ "{}{}{}{}".format(
+ color,
+ Log.style.BOLD,
+ text.rjust(Log.terminal_columns - Log.current_cursor_pos),
+ Log.style.RESET,
+ )
+ )
+ f = open(Log.log_file, "a")
+ f.write("{}\n".format(text))
+ if result_text:
+ print("Results of call before:{}\n".format(result_text))
+ f.write("Results of call before:{}\n".format(result_text))
+ f.close()
+
+ def PrintFatal(error_text):
+ # datetime object containing current date and time
+ dt_string = datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S")
+ Log.current_cursor_pos = len(error_text) + len(dt_string) + 3
+
+ print(
+ "[{}{}{}] {}{}FATAL: {}{}".format(
+ Log.style.YELLOW,
+ dt_string,
+ Log.style.RESET,
+ Log.style.RED,
+ Log.style.BOLD,
+ Log.style.RESET,
+ error_text,
+ )
+ )
+ with open(Log.log_file, "a") as f:
+ f.write("[{}] {}\n".format(dt_string, error_text))
+
+ def __printUsedBooleanValueLine(name, value):
+ text = "--{} = {}{}".format(
+ name,
+ Log.style.RED + "yes" if value else Log.style.GREEN + "no",
+ Log.style.RESET,
+ )
+ print(
+ "│ {}{}{}{}{}│".format(
+ Log.style.BOLD,
+ Log.style.WHITE,
+ text,
+ Log.style.RESET,
+ " " * (Log.terminal_columns - len(text) + 6),
+ )
+ )
diff --git a/xbmc/addons/kodi-dev-kit/tools/debian-addon-package-test.sh b/xbmc/addons/kodi-dev-kit/tools/debian-addon-package-test.sh
new file mode 100755
index 0000000..d778954
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/tools/debian-addon-package-test.sh
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+# This script is for purely testing purposes!
+#
+# It is meant to be able to test at binary addons the creation of a debian
+# package.
+#
+# The created files are below the source code folder.
+#
+# Example:
+# ./build-debian-addon-package.sh $HOME/your_path/screensaver.stars
+#
+# To remove generated code:
+# ./build-debian-addon-package.sh $HOME/your_path/screensaver.stars --clean
+#
+
+BASE_DIR=""
+REPO_DIR=""
+PACKAGEVERSION=""
+VERSION_MAIN=""
+VERSION_MINOR=""
+VERSION_REVISON=""
+GIT_REV=""
+DIST=""
+TAGREV=${TAGREV:-"0"}
+
+function usage {
+ echo "\
+--------------------------------------------------------------------------------
+
+This script builds a Kodi addon debian package from the given addon source.
+
+As value, the path to the addon must be given.
+In addition --clean can be used to remove the created debian files.
+
+WARNING: This script is for testing purposes only!
+
+--------------------------------------------------------------------------------"
+}
+
+function checkEnv {
+ echo "#------ build environment ------#"
+ echo "BASE_DIR: $BASE_DIR"
+ echo "REPO_DIR: $REPO_DIR"
+ getVersion
+ echo "VERSION_MAIN: $VERSION_MAIN"
+ echo "VERSION_MINOR: $VERSION_MINOR"
+ echo "VERSION_REVISON: $VERSION_REVISON"
+ if [ $GIT_REV ]; then
+ echo "GIT_REV: $GIT_REV"
+ fi
+ echo "TAGREV: $TAGREV"
+ echo "DIST: $DIST"
+ echo "ARCHS: $ARCHS"
+
+ echo "#-------------------------------#"
+}
+
+function getVersion {
+ if [ -d ${BASE_DIR}/.git ]; then
+ getGitRev
+ fi
+ PACKAGEVERSION=$(cat ${BASE_DIR}/$REPO_DIR/addon.xml.in | sed -n '/version/ s/.*version=\"\([0-9]\+\.[0-9]\+\.[0-9]\+\)\".*/\1/p' | awk 'NR == 1')
+ VERSION_MAIN=$(echo $PACKAGEVERSION | awk -F. '{print $1}')
+ VERSION_MINOR=$(echo $PACKAGEVERSION | awk -F. '{print $2}')
+ VERSION_REVISON=$(echo $PACKAGEVERSION | awk -F. '{print $3}')
+}
+
+function getGitRev {
+ cd $BASE_DIR || exit 1
+ GIT_REV=$(git log -1 --pretty=format:"%h")
+}
+
+function cleanup() {
+ echo "Starting to remove debian generated files"
+ cd ${BASE_DIR}
+ rm -rf obj-$ARCHS-linux-gnu
+ rm -rf debian/.debhelper
+ rm -rf debian/"kodi-"$(echo $REPO_DIR | tr . -)
+ rm -rf debian/"kodi-"$(echo $REPO_DIR | tr . -)-dbg
+ rm -rf debian/tmp
+ rm -f debian/changelog
+ rm -f debian/debhelper-build-stamp
+ rm -f debian/files
+ rm -f debian/*.log
+ rm -f debian/*.substvars
+}
+
+if [[ $1 = "-h" ]] || [[ $1 = "--help" ]]; then
+ echo "$0:"
+ usage
+ exit
+fi
+
+if [ ! $1 ] || [ ${1} = "--clean" ]; then
+ printf "$0:\nERROR: Addon source code must be given as the first parameter!\n"
+ usage
+ exit 1
+elif [ ! -d $1 ]; then
+ printf "$0:\nERROR: Given folder is not present or not a valid addon source!\n"
+ usage
+ exit 1
+fi
+
+ARCHS=$(uname -m)
+BASE_DIR=$(realpath ${1})
+REPO_DIR=$(basename ${1})
+DIST=$(lsb_release -cs)
+
+if [ ! -f ${BASE_DIR}/$REPO_DIR/addon.xml.in ]; then
+ echo "$0:
+ERROR: \"required $REPO_DIR/addon.xml.in\" not found!
+
+The base source dir and addon.xml.in containing directory names must be equal"
+ usage
+ exit 1
+fi
+
+checkEnv
+
+ORIGTARBALL="kodi-"$(echo $REPO_DIR | tr . -)"_${PACKAGEVERSION}.orig.tar.gz"
+
+if [[ ${2} = "--clean" ]]; then
+ cleanup
+ exit
+fi
+
+echo "Detected addon package version: ${PACKAGEVERSION}"
+
+sed -e "s/#PACKAGEVERSION#/${PACKAGEVERSION}/g" \
+ -e "s/#TAGREV#/${TAGREV}/g" \
+ -e "s/#DIST#/${DIST}/g" ${BASE_DIR}/debian/changelog.in > ${BASE_DIR}/debian/changelog
+
+echo "Create needed compressed source code file: ${BASE_DIR}/../${ORIGTARBALL}.tar.gz"
+
+# git archive --format=tar.gz -o ${BASE_DIR}/../${ORIGTARBALL} HEAD # Unused git, leaved as optional way
+EXCLUDE=$(cat .gitignore | sed -e '/#/d' -e '/^\s*$/d' -e 's/^/--exclude=/' -e 's/\/$//' | tr '\n' ' ')
+tar -zcvf ${BASE_DIR}/../${ORIGTARBALL} --exclude=.git $EXCLUDE * # Used to prevent on code changed for test a git commit
+
+echo "Building debian-source package for ${DIST}"
+dpkg-buildpackage -us -uc --diff-ignore="()$"
diff --git a/xbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py b/xbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py
new file mode 100755
index 0000000..0b0590e
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py
@@ -0,0 +1,190 @@
+#!/usr/bin/env python3
+
+from optparse import OptionParser
+import glob
+import io
+import os
+import re
+import sys
+
+def read_file(name, normalize=True):
+ """ Read a file. """
+ try:
+ with open(name, 'r', encoding='utf-8') as f:
+ # read the data
+ data = f.read()
+ if normalize:
+ # normalize line endings
+ data = data.replace("\r\n", "\n")
+ return data
+ except IOError as e:
+ (errno, strerror) = e.args
+ sys.stderr.write('Failed to read file ' + name + ': ' + strerror)
+ raise
+
+def write_file(name, data):
+ """ Write a file. """
+ try:
+ with open(name, 'w', encoding='utf-8') as f:
+ # write the data
+ if sys.version_info.major == 2:
+ f.write(data.decode('utf-8'))
+ else:
+ f.write(data)
+ except IOError as e:
+ (errno, strerror) = e.args
+ sys.stderr.write('Failed to write file ' + name + ': ' + strerror)
+ raise
+
+def auto_check_header(file):
+ groups_to_check = []
+
+ data = read_file(file)
+ if not 'addon_auto_check' in data:
+ return ''
+
+ for line in io.StringIO(data):
+ line = re.search(r"^.*\/\/\/.*@copydetails *(.*)(_header|_source)_addon_auto_check.*", line, flags=re.UNICODE)
+ if line and line.group(1):
+ group = line.group(1)
+ if group in groups_to_check:
+ continue
+
+ print(' - Found use with %s' % group)
+ groups_to_check.append(line.group(1))
+
+ return groups_to_check
+
+def parse_header(file, group, new_path=''):
+ header_sources = ''
+ header_addon = ''
+ source_addon = ''
+
+ data = read_file(file)
+ group_found = False
+ group_start = False
+ virtual_function_start = False
+ for line in io.StringIO(data):
+ if not group_found and 'defgroup ' + group in line:
+ group_found = True
+ continue
+ elif group_found and not group_start and '///@{' in line:
+ group_start = True
+ continue
+ elif group_start and '///@}' in line:
+ break
+ elif re.match(r'^.*//.*', line) or re.match(r'^.*//.*', line) or line == '\n' or not group_start:
+ continue
+
+ if re.match(r'^.*virtual.*', line):
+ virtual_function_start = True
+
+ if virtual_function_start:
+ header_sources += re.sub(r"^\s+", "", line, flags=re.UNICODE)
+
+ if virtual_function_start and re.match(r'^.*}.*', line):
+ virtual_function_start = False
+
+ if not group_found:
+ return ""
+
+ header_sources = header_sources.replace("\n", "")
+ header_sources = " ".join(re.split("\s+", header_sources, flags=re.UNICODE))
+ header_sources = header_sources.replace("}", "}\n")
+ header_sources = header_sources.replace("= 0;", "= 0;\n")
+ header_sources = header_sources.replace(",", ", ")
+
+ # Generate class header part of list
+ header_addon += '/// @defgroup ' + group + '_header_addon_auto_check Group header include\n'
+ header_addon += '/// @ingroup ' + group + '\n'
+ header_addon += '///@{\n'
+ header_addon += '/// *Header parts:*\n'
+ header_addon += '/// ~~~~~~~~~~~~~{.cpp}\n'
+ header_addon += '///\n'
+ for line in io.StringIO(header_sources):
+ line = re.search(r"^.*virtual.([A-Za-z1-9].*\(.*\))", line, flags=re.UNICODE)
+ if line:
+ header_addon += '/// ' + re.sub(' +', ' ', line.group(1)) + ' override;\n'
+ header_addon += '///\n'
+ header_addon += '/// ~~~~~~~~~~~~~\n'
+ header_addon += '///@}\n\n'
+
+ # Generate class source part of list
+ source_addon += '/// @defgroup ' + group + '_source_addon_auto_check Group source include\n'
+ source_addon += '/// @ingroup ' + group + '\n'
+ source_addon += '///@{\n'
+ source_addon += '/// *Source parts:*\n'
+ source_addon += '/// ~~~~~~~~~~~~~{.cpp}\n'
+ source_addon += '///\n'
+ for line in io.StringIO(header_sources):
+ line = line.replace("{", "\n{\n ")
+ line = line.replace("}", "\n}")
+ for line in io.StringIO(line + '\n'):
+ func = re.search(r"^.*(virtual *) *(.*) ([a-z|A-Z|0-9].*)(\(.*\))", line, flags=re.UNICODE)
+ if func:
+ source_addon += '/// ' + re.sub(' +', ' ', func.group(2) + ' CMyInstance::' + func.group(3) + func.group(4) + '\n')
+ else:
+ source_addon += '/// ' + line
+ if '= 0' in line:
+ source_addon += '/// {\n'
+ source_addon += '/// // Required in interface to have!\n'
+ source_addon += '/// // ...\n'
+ source_addon += '/// }\n'
+
+ source_addon += '/// ~~~~~~~~~~~~~\n'
+ source_addon += '///@}\n\n'
+
+ return header_addon + source_addon
+
+def print_error(msg):
+ print('Error: %s\nSee --help for usage.' % msg)
+
+# cannot be loaded as a module
+if __name__ != "__main__":
+ sys.stderr.write('This file cannot be loaded as a module!')
+ sys.exit()
+
+# parse command-line options
+disc = """
+This utility generate group list about addon header sources to add inside doxygen.
+"""
+
+parser = OptionParser(description=disc)
+parser.add_option(
+ '--header-file',
+ dest='headerfile',
+ metavar='DIR',
+ help='the to checked header [required]')
+parser.add_option(
+ '--doxygen-group',
+ dest='doxygengroup',
+ help='the to checked doxygen group inside header [required]')
+(options, args) = parser.parse_args()
+
+docs = ''
+groups_to_check = []
+
+# Check about use of helper docs
+if options.doxygengroup is None:
+ print('Scaning about used places...')
+ headers = glob.glob("../include/kodi/**/*.h", recursive=True)
+ for header in headers:
+ group = auto_check_header(header)
+ if group:
+ groups_to_check += group
+else:
+ groups_to_check.append(options.doxygengroup)
+
+# Generate the helper docs
+if options.headerfile is None:
+ headers = glob.glob("../include/kodi/**/*.h", recursive=True)
+ print('Parsing about docs:')
+ for header in headers:
+ print(' - %s' % header)
+ for group in groups_to_check:
+ docs += parse_header(header, group)
+else:
+ for group in groups_to_check:
+ docs += parse_header(options.headerfile, group)
+
+write_file("../include/groups.dox", docs)