aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE.md7
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md1
-rw-r--r--.gitignore2
-rw-r--r--addons/resource.language.en_gb/resources/strings.po199
-rw-r--r--addons/skin.estouchy/addon.xml2
-rw-r--r--addons/skin.estouchy/changelog.txt13
-rw-r--r--addons/skin.estouchy/xml/CustomVolume.xml32
-rw-r--r--addons/skin.estouchy/xml/DialogAddonInfo.xml27
-rw-r--r--addons/skin.estouchy/xml/DialogPVRInfo.xml6
-rw-r--r--addons/skin.estouchy/xml/DialogVolumeBar.xml32
-rw-r--r--addons/skin.estouchy/xml/Includes.xml108
-rw-r--r--addons/skin.estouchy/xml/IncludesPlayerControls.xml17
-rw-r--r--addons/skin.estouchy/xml/MyPVRChannels.xml5
-rw-r--r--addons/skin.estouchy/xml/MyPVRGuide.xml5
-rw-r--r--addons/skin.estouchy/xml/MyPVRRecordings.xml5
-rw-r--r--addons/skin.estouchy/xml/MyPVRSearch.xml5
-rw-r--r--addons/skin.estouchy/xml/MyPVRTimers.xml5
-rw-r--r--addons/skin.estouchy/xml/ViewsWide.xml26
-rw-r--r--addons/skin.estuary/language/resource.language.en_gb/strings.po5
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/enabled-broken.pngbin0 -> 889 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/enabled-deprecated.pngbin0 -> 423 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/enabled-normal.pngbin0 -> 267 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/install-pinned.pngbin0 -> 652 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/install.pngbin378 -> 546 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/manual-pinned.pngbin0 -> 695 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/manual.pngbin0 -> 596 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/official-pinned.pngbin0 -> 569 bytes
-rw-r--r--addons/skin.estuary/media/icons/addonstatus/official.pngbin0 -> 469 bytes
-rw-r--r--addons/skin.estuary/xml/AddonBrowser.xml20
-rw-r--r--addons/skin.estuary/xml/DialogAddonInfo.xml142
-rw-r--r--addons/skin.estuary/xml/Includes.xml95
-rw-r--r--addons/skin.estuary/xml/MusicVisualisation.xml2
-rw-r--r--addons/skin.estuary/xml/SettingsCategory.xml64
-rw-r--r--addons/skin.estuary/xml/SettingsProfile.xml10
-rw-r--r--addons/skin.estuary/xml/SettingsSystemInfo.xml26
-rw-r--r--addons/skin.estuary/xml/SkinSettings.xml22
-rw-r--r--addons/skin.estuary/xml/Variables.xml21
-rw-r--r--addons/skin.estuary/xml/View_55_WideList.xml20
-rw-r--r--addons/xbmc.addon/metadata.xsd17
-rw-r--r--cmake/addons/CMakeLists.txt72
-rw-r--r--cmake/addons/README.md12
-rw-r--r--cmake/cpack/deb/packages/kodi.txt.in2
l---------cmake/installdata/rbpi/lirc.txt1
-rw-r--r--cmake/modules/FindEGL.cmake8
-rw-r--r--cmake/modules/FindLCMS2.cmake4
-rw-r--r--cmake/modules/FindLibDRM.cmake2
-rw-r--r--cmake/modules/FindLibDvd.cmake15
-rw-r--r--cmake/modules/FindMMAL.cmake55
-rw-r--r--cmake/modules/FindOpenGLES.cmake8
-rw-r--r--cmake/modules/FindPlist.cmake4
-rw-r--r--cmake/platform/freebsd/rbpi.cmake1
-rw-r--r--cmake/platform/linux/rbpi.cmake3
-rw-r--r--cmake/scripts/common/CompilerSettings.cmake4
-rw-r--r--cmake/scripts/darwin_embedded/ExtraTargets.cmake5
-rw-r--r--cmake/scripts/linux/ArchSetup.cmake10
-rw-r--r--cmake/scripts/windowsstore/ArchSetup.cmake1
-rw-r--r--cmake/treedata/common/rbpi/rbpi.txt2
-rw-r--r--cmake/treedata/common/subdirs.txt8
-rw-r--r--cmake/treedata/freebsd/subdirs.txt2
-rw-r--r--cmake/treedata/linux/subdirs.txt2
-rw-r--r--docs/README.Android.md1
-rw-r--r--docs/README.Fedora.md2
-rw-r--r--docs/README.FreeBSD.md3
-rw-r--r--docs/README.Linux.md5
-rw-r--r--docs/README.RaspberryPi.md239
-rw-r--r--docs/README.Ubuntu.md2
-rw-r--r--docs/README.Windows.md4
-rw-r--r--docs/README.iOS.md5
-rw-r--r--docs/README.macOS.md1
-rw-r--r--docs/README.md1
-rw-r--r--docs/README.openSUSE.md2
-rw-r--r--docs/README.tvOS.md1
-rw-r--r--docs/resources/raspberrypi.svg30
-rw-r--r--system/keymaps/customcontroller.SiriRemote.xml2
-rw-r--r--system/settings/rbp.xml123
-rw-r--r--system/settings/rbp2.xml28
-rw-r--r--system/settings/wayland.xml40
-rw-r--r--tools/buildsteps/defaultenv6
-rw-r--r--tools/buildsteps/linux-arm-gbm/configure-depends9
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/configure-xbmc (renamed from tools/buildsteps/rbpi/configure-xbmc)2
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/make-binary-addons (renamed from tools/buildsteps/rbpi/make-binary-addons)2
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/make-depends (renamed from tools/buildsteps/rbpi/make-depends)3
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/make-native-depends (renamed from tools/buildsteps/rbpi/make-native-depends)4
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/make-xbmc (renamed from tools/buildsteps/rbpi/make-xbmc)2
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/package (renamed from tools/buildsteps/rbpi/package)4
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/prepare-depends (renamed from tools/buildsteps/rbpi/prepare-depends)11
-rw-r--r--[-rwxr-xr-x]tools/buildsteps/linux-arm-gbm/prepare-xbmc (renamed from tools/buildsteps/rbpi/prepare-xbmc)4
-rw-r--r--tools/buildsteps/linux-arm-gbm/run-tests14
-rwxr-xr-xtools/buildsteps/rbpi/configure-depends12
-rw-r--r--tools/buildsteps/windows/BuildSetup.bat41
-rw-r--r--tools/buildsteps/windows/vswhere.bat2
-rwxr-xr-xtools/darwin/Support/Codesign-topshelf.command17
-rwxr-xr-xtools/darwin/Support/Codesign.command61
-rw-r--r--tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in1
-rw-r--r--tools/depends/README.md21
-rw-r--r--tools/depends/configure.ac72
-rw-r--r--tools/depends/m4/ax_cxx_compile_stdcxx.m4951
-rw-r--r--tools/depends/m4/ax_cxx_compile_stdcxx_14.m4146
-rw-r--r--tools/depends/m4/xbmc_arch.m43
-rw-r--r--tools/depends/native/Makefile14
-rw-r--r--tools/depends/native/Mako/Makefile29
-rw-r--r--tools/depends/native/MarkupSafe/Makefile29
-rw-r--r--tools/depends/native/gen_entitlements/Makefile14
-rwxr-xr-xtools/depends/native/gen_entitlements/gen_entitlements.py36
-rw-r--r--tools/depends/native/meson/Makefile2
-rw-r--r--tools/depends/target/Makefile33
-rw-r--r--tools/depends/target/Toolchain.cmake.in16
-rw-r--r--tools/depends/target/Toolchain_binaddons.cmake.in17
-rw-r--r--tools/depends/target/dav1d/Makefile2
-rw-r--r--tools/depends/target/ffmpeg/CMakeLists.txt37
-rw-r--r--tools/depends/target/ffmpeg/FFMPEG-VERSION2
-rw-r--r--tools/depends/target/libandroidjni/Makefile2
-rw-r--r--tools/depends/target/libdrm/Makefile76
-rw-r--r--tools/depends/target/libfmt/Makefile2
-rw-r--r--tools/depends/target/libinput/Makefile2
-rw-r--r--tools/depends/target/libspdlog/Makefile2
-rw-r--r--tools/depends/target/libva/Makefile64
-rw-r--r--tools/depends/target/mesa/Makefile93
-rwxr-xr-xtools/depends/target/meson-cross-setup.sh10
-rw-r--r--tools/depends/target/nettle/02-conftest_exit.patch21
-rw-r--r--tools/depends/target/nettle/Makefile4
-rw-r--r--tools/depends/target/p8-platform/0001-fix-c++17-support.patch22
-rw-r--r--tools/depends/target/p8-platform/Makefile4
-rw-r--r--tools/depends/xbmc-addons.include5
-rw-r--r--xbmc/Application.cpp27
-rw-r--r--xbmc/GUIInfoManager.cpp175
-rw-r--r--xbmc/GUIInfoManager.h1
-rw-r--r--xbmc/LangInfo.cpp28
-rw-r--r--xbmc/SystemGlobals.cpp8
-rw-r--r--xbmc/TextureCacheJob.cpp17
-rw-r--r--xbmc/Util.cpp33
-rw-r--r--xbmc/XBDateTime.cpp136
-rw-r--r--xbmc/XBDateTime.h8
-rw-r--r--xbmc/addons/Addon.h6
-rw-r--r--xbmc/addons/AddonBindings.cmake2
-rw-r--r--xbmc/addons/AddonDatabase.cpp222
-rw-r--r--xbmc/addons/AddonDatabase.h63
-rw-r--r--xbmc/addons/AddonEvents.h8
-rw-r--r--xbmc/addons/AddonInstaller.cpp50
-rw-r--r--xbmc/addons/AddonManager.cpp149
-rw-r--r--xbmc/addons/AddonManager.h101
-rw-r--r--xbmc/addons/AddonRepos.cpp31
-rw-r--r--xbmc/addons/AddonRepos.h20
-rw-r--r--xbmc/addons/AddonUpdateRules.cpp102
-rw-r--r--xbmc/addons/AddonUpdateRules.h87
-rw-r--r--xbmc/addons/CMakeLists.txt2
-rw-r--r--xbmc/addons/ContextMenus.cpp6
-rw-r--r--xbmc/addons/IAddon.h6
-rw-r--r--xbmc/addons/Repository.cpp17
-rw-r--r--xbmc/addons/Repository.h9
-rw-r--r--xbmc/addons/VFSEntry.cpp176
-rw-r--r--xbmc/addons/VFSEntry.h12
-rw-r--r--xbmc/addons/addoninfo/AddonExtensions.h2
-rw-r--r--xbmc/addons/addoninfo/AddonInfo.h35
-rw-r--r--xbmc/addons/addoninfo/AddonInfoBuilder.cpp29
-rw-r--r--xbmc/addons/addoninfo/AddonInfoBuilder.h22
-rw-r--r--xbmc/addons/addoninfo/AddonType.h2
-rw-r--r--xbmc/addons/gui/CMakeLists.txt2
-rw-r--r--xbmc/addons/gui/GUIDialogAddonInfo.cpp44
-rw-r--r--xbmc/addons/gui/GUIHelpers.cpp46
-rw-r--r--xbmc/addons/gui/GUIHelpers.h38
-rw-r--r--xbmc/addons/gui/GUIWindowAddonBrowser.cpp19
-rw-r--r--xbmc/addons/interfaces/Filesystem.cpp46
-rw-r--r--xbmc/addons/interfaces/Filesystem.h1
-rw-r--r--xbmc/addons/interfaces/gui/CMakeLists.txt6
-rw-r--r--xbmc/addons/interfaces/gui/GUITranslator.cpp969
-rw-r--r--xbmc/addons/interfaces/gui/GUITranslator.h41
-rw-r--r--xbmc/addons/interfaces/gui/General.cpp44
-rw-r--r--xbmc/addons/interfaces/gui/General.h22
-rw-r--r--xbmc/addons/interfaces/gui/ListItem.cpp192
-rw-r--r--xbmc/addons/interfaces/gui/ListItem.h51
-rw-r--r--xbmc/addons/interfaces/gui/Window.cpp617
-rw-r--r--xbmc/addons/interfaces/gui/Window.h229
-rw-r--r--xbmc/addons/interfaces/gui/controls/Button.cpp66
-rw-r--r--xbmc/addons/interfaces/gui/controls/Button.h22
-rw-r--r--xbmc/addons/interfaces/gui/controls/Edit.cpp96
-rw-r--r--xbmc/addons/interfaces/gui/controls/Edit.h33
-rw-r--r--xbmc/addons/interfaces/gui/controls/FadeLabel.cpp55
-rw-r--r--xbmc/addons/interfaces/gui/controls/FadeLabel.h26
-rw-r--r--xbmc/addons/interfaces/gui/controls/Image.cpp40
-rw-r--r--xbmc/addons/interfaces/gui/controls/Image.h21
-rw-r--r--xbmc/addons/interfaces/gui/controls/Label.cpp37
-rw-r--r--xbmc/addons/interfaces/gui/controls/Label.h16
-rw-r--r--xbmc/addons/interfaces/gui/controls/Progress.cpp37
-rw-r--r--xbmc/addons/interfaces/gui/controls/Progress.h16
-rw-r--r--xbmc/addons/interfaces/gui/controls/RadioButton.cpp67
-rw-r--r--xbmc/addons/interfaces/gui/controls/RadioButton.h22
-rw-r--r--xbmc/addons/interfaces/gui/controls/Rendering.cpp37
-rw-r--r--xbmc/addons/interfaces/gui/controls/Rendering.h52
-rw-r--r--xbmc/addons/interfaces/gui/controls/SettingsSlider.cpp149
-rw-r--r--xbmc/addons/interfaces/gui/controls/SettingsSlider.h48
-rw-r--r--xbmc/addons/interfaces/gui/controls/Slider.cpp143
-rw-r--r--xbmc/addons/interfaces/gui/controls/Slider.h48
-rw-r--r--xbmc/addons/interfaces/gui/controls/Spin.cpp169
-rw-r--r--xbmc/addons/interfaces/gui/controls/Spin.h58
-rw-r--r--xbmc/addons/interfaces/gui/controls/TextBox.cpp64
-rw-r--r--xbmc/addons/interfaces/gui/controls/TextBox.h23
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/ContextMenu.cpp27
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/ContextMenu.h15
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.cpp159
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.h35
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/FileBrowser.cpp205
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/FileBrowser.h87
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Keyboard.cpp176
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Keyboard.h65
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Numeric.cpp123
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Numeric.h43
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/OK.cpp39
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/OK.h20
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Progress.cpp135
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Progress.h39
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Select.cpp51
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/Select.h26
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/TextViewer.cpp25
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/TextViewer.h12
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/YesNo.cpp66
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/YesNo.h16
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Doxyfile6
-rw-r--r--xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox13
-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/include/kodi/AddonBase.h4
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h52
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h4
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioEncoder.h4
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/CMakeLists.txt1
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h1600
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/ImageDecoder.h2
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h4
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h1634
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h735
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h709
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Visualization.h4
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/CMakeLists.txt5
-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/c-api/CMakeLists.txt4
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/CMakeLists.txt3
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/game.h1212
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/peripheral.h709
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_general.h2
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/vfs.h149
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h17
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/CMakeLists.txt8
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/CMakeLists.txt16
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/button.h35
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/edit.h79
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/fade_label.h34
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/image.h37
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/label.h32
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/progress.h32
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/radio_button.h35
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/rendering.h38
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/settings_slider.h48
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/slider.h48
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/spin.h58
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/text_box.h36
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/definitions.h106
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/CMakeLists.txt14
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/context_menu.h33
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/extended_progress.h43
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/filebrowser.h77
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/keyboard.h74
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/numeric.h54
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/ok.h37
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/progress.h45
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/select.h42
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/text_viewer.h30
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/yes_no.h50
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/general.h37
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/CMakeLists.txt5
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/action_ids.h763
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/list_item.h54
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/window.h183
-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.txt1
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h295
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/ListItem.h587
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/Window.h1716
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Button.h117
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Edit.h224
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/FadeLabel.h103
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Image.h60
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Label.h81
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Progress.h82
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/RadioButton.h171
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Rendering.h158
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/SettingsSlider.h246
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Slider.h241
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Spin.h677
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/TextBox.h86
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/definitions.h433
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ContextMenu.h319
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h130
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/FileBrowser.h546
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Keyboard.h758
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Numeric.h646
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/OK.h152
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Progress.h113
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Select.h454
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/TextViewer.h171
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/YesNo.h326
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h107
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GLonDX.h124
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/Shader.h131
-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.txt5
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/gui/renderHelper.h8
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/platform/android/System.h77
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/versions.h24
-rw-r--r--xbmc/addons/test/TestAddonBuilder.cpp6
-rw-r--r--xbmc/addons/test/TestAddonDatabase.cpp7
-rw-r--r--xbmc/addons/test/TestAddonInfoBuilder.cpp5
-rw-r--r--xbmc/commons/ilog.h10
-rw-r--r--xbmc/cores/AudioEngine/AEResampleFactory.cpp10
-rw-r--r--xbmc/cores/AudioEngine/CMakeLists.txt9
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp4
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp589
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h54
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp605
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkPi.h57
-rw-r--r--xbmc/cores/RetroPlayer/process/rbpi/CMakeLists.txt7
-rw-r--r--xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.cpp26
-rw-r--r--xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.h26
-rw-r--r--xbmc/cores/VideoPlayer/Buffers/CMakeLists.txt2
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/CMakeLists.txt9
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp53
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.cpp860
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h117
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp371
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h73
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp4
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt7
-rw-r--r--xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.cpp47
-rw-r--r--xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.h45
-rw-r--r--xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.cpp6
-rw-r--r--xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp3
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayerRadioRDS.cpp12
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp43
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h14
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/CMakeLists.txt18
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp1570
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h215
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp45
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp22
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp11
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp40
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h28
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp16
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h2
-rw-r--r--xbmc/cores/VideoSettings.h4
-rw-r--r--xbmc/cores/omxplayer/CMakeLists.txt6
-rw-r--r--xbmc/cores/omxplayer/OMXImage.cpp2340
-rw-r--r--xbmc/cores/omxplayer/OMXImage.h185
-rw-r--r--xbmc/dbwrappers/Database.cpp52
-rw-r--r--xbmc/dbwrappers/Database.h30
-rw-r--r--xbmc/dbwrappers/dataset.cpp22
-rw-r--r--xbmc/dbwrappers/dataset.h13
-rw-r--r--xbmc/filesystem/AddonsDirectory.cpp35
-rw-r--r--xbmc/filesystem/FileDirectoryFactory.cpp25
-rw-r--r--xbmc/filesystem/IFileTypes.h1
-rw-r--r--xbmc/games/addons/GameClient.cpp69
-rw-r--r--xbmc/games/addons/GameClient.h52
-rw-r--r--xbmc/games/addons/GameClientInGameSaves.cpp4
-rw-r--r--xbmc/games/addons/GameClientSubsystem.cpp2
-rw-r--r--xbmc/games/addons/input/GameClientInput.cpp27
-rw-r--r--xbmc/guilib/CMakeLists.txt5
-rw-r--r--xbmc/guilib/Texture.h5
-rw-r--r--xbmc/guilib/TexturePi.cpp137
-rw-r--r--xbmc/guilib/TexturePi.h33
-rw-r--r--xbmc/guilib/guiinfo/AddonsGUIInfo.cpp37
-rw-r--r--xbmc/guilib/guiinfo/GUIControlsGUIInfo.cpp2
-rw-r--r--xbmc/guilib/guiinfo/GUIInfoLabels.h102
-rw-r--r--xbmc/guilib/guiinfo/MusicGUIInfo.cpp19
-rw-r--r--xbmc/guilib/guiinfo/SystemGUIInfo.cpp7
-rw-r--r--xbmc/guilib/guiinfo/VideoGUIInfo.cpp5
-rw-r--r--xbmc/input/InputManager.cpp1
-rw-r--r--xbmc/input/actions/ActionIDs.h5
-rw-r--r--xbmc/interfaces/json-rpc/AddonsOperations.cpp8
-rw-r--r--xbmc/interfaces/json-rpc/schema/types.json5
-rw-r--r--xbmc/interfaces/json-rpc/schema/version.txt2
-rw-r--r--xbmc/interfaces/legacy/ListItem.h13
-rw-r--r--xbmc/interfaces/legacy/ModuleXbmc.cpp2
-rw-r--r--xbmc/interfaces/legacy/ModuleXbmc.h2
-rw-r--r--xbmc/interfaces/legacy/WindowXML.h8
-rw-r--r--xbmc/listproviders/DirectoryProvider.cpp3
-rw-r--r--xbmc/music/MusicDatabase.cpp4
-rw-r--r--xbmc/music/MusicDatabase.h1
-rw-r--r--xbmc/network/AirTunesServer.cpp6
-rw-r--r--xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp4
-rw-r--r--xbmc/peripherals/PeripheralTypes.h5
-rw-r--r--xbmc/peripherals/addons/AddonButtonMap.h1
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.cpp84
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.h1
-rw-r--r--xbmc/peripherals/addons/PeripheralAddonTranslator.h1
-rw-r--r--xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp5
-rw-r--r--xbmc/pictures/Picture.cpp10
-rw-r--r--xbmc/pictures/PictureInfoTag.cpp375
-rw-r--r--xbmc/pictures/PictureInfoTag.h102
-rw-r--r--xbmc/platform/android/peripherals/AndroidJoystickState.h2
-rw-r--r--xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm2
-rw-r--r--xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.h2
-rw-r--r--xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.mm2
-rw-r--r--xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbeddedManager.h2
-rw-r--r--xbmc/platform/darwin/tvos/TVOSTopShelf.mm158
-rw-r--r--xbmc/platform/darwin/tvos/TopShelf/ServiceProvider.mm45
-rw-r--r--xbmc/platform/linux/CMakeLists.txt11
-rw-r--r--xbmc/platform/linux/DllBCM.h257
-rw-r--r--xbmc/platform/linux/DllOMX.h103
-rw-r--r--xbmc/platform/linux/OMXCore.cpp1792
-rw-r--r--xbmc/platform/linux/OMXCore.h204
-rw-r--r--xbmc/platform/linux/RBP.cpp494
-rw-r--r--xbmc/platform/linux/RBP.h124
-rw-r--r--xbmc/platform/linux/input/CMakeLists.txt2
-rw-r--r--xbmc/platform/linux/rpi/rpi_user_vcsm.h425
-rw-r--r--xbmc/platform/linux/test/TestSysfsPath.cpp16
-rw-r--r--xbmc/platform/xbmc.cpp14
-rw-r--r--xbmc/pvr/epg/Epg.cpp8
-rw-r--r--xbmc/pvr/epg/Epg.h7
-rw-r--r--xbmc/pvr/epg/EpgContainer.cpp14
-rw-r--r--xbmc/pvr/epg/EpgDatabase.cpp44
-rw-r--r--xbmc/pvr/epg/EpgDatabase.h37
-rw-r--r--xbmc/pvr/epg/EpgInfoTag.cpp17
-rw-r--r--xbmc/pvr/epg/EpgInfoTag.h7
-rw-r--r--xbmc/pvr/epg/EpgTagsContainer.cpp102
-rw-r--r--xbmc/pvr/epg/EpgTagsContainer.h6
-rw-r--r--xbmc/pvr/recordings/PVRRecording.cpp10
-rw-r--r--xbmc/pvr/recordings/PVRRecording.h12
-rw-r--r--xbmc/rendering/gles/RenderSystemGLES.cpp3
-rw-r--r--xbmc/settings/AdvancedSettings.cpp2
-rw-r--r--xbmc/settings/SettingPath.cpp10
-rw-r--r--xbmc/settings/Settings.cpp9
-rw-r--r--xbmc/settings/Settings.h1
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.cpp12
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.h2
-rw-r--r--xbmc/test/TestDateTime.cpp15
-rw-r--r--xbmc/utils/EGLUtils.cpp32
-rw-r--r--xbmc/utils/GLUtils.cpp52
-rw-r--r--xbmc/utils/RecentlyAddedJob.cpp2
-rw-r--r--xbmc/utils/SystemInfo.cpp4
-rw-r--r--xbmc/utils/log.cpp4
-rw-r--r--xbmc/utils/test/TestSystemInfo.cpp4
-rw-r--r--xbmc/utils/test/Testlog.cpp6
-rw-r--r--xbmc/video/VideoDatabase.cpp55
-rw-r--r--xbmc/video/VideoDatabase.h1
-rw-r--r--xbmc/video/VideoInfoScanner.h11
-rw-r--r--xbmc/video/VideoInfoTag.h4
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoSettings.cpp4
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp30
-rw-r--r--xbmc/windowing/gbm/DRMUtils.cpp64
-rw-r--r--xbmc/windowing/gbm/DRMUtils.h5
-rw-r--r--xbmc/windowing/rpi/CMakeLists.txt14
-rw-r--r--xbmc/windowing/rpi/RPIUtils.cpp602
-rw-r--r--xbmc/windowing/rpi/RPIUtils.h50
-rw-r--r--xbmc/windowing/rpi/VideoSyncPi.cpp68
-rw-r--r--xbmc/windowing/rpi/VideoSyncPi.h27
-rw-r--r--xbmc/windowing/rpi/WinSystemRpi.cpp255
-rw-r--r--xbmc/windowing/rpi/WinSystemRpi.h63
-rw-r--r--xbmc/windowing/rpi/WinSystemRpiGLESContext.cpp189
-rw-r--r--xbmc/windowing/rpi/WinSystemRpiGLESContext.h44
-rw-r--r--xbmc/windowing/wayland/WinSystemWaylandEGLContextGLES.cpp5
-rw-r--r--xbmc/windows/GUIWindowSystemInfo.cpp2
478 files changed, 22060 insertions, 24478 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 0dc08a7caf..a99bc4303b 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -38,7 +38,7 @@ Steps to reproduce the behavior:
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->
<!--- Put your text below this line -->
-1.
+1.
2.
3.
@@ -50,7 +50,7 @@ The debuglog can be found here:
-### Screenshots
+### Screenshots
Here are some links or screenshots to help explain the problem:
<!--- Put your text below this line -->
@@ -71,7 +71,6 @@ Used Operating system:
- [ ] iOS
- [ ] Linux
- [ ] OSX
- - [ ] Raspberry-Pi
- [ ] Windows
- [ ] Windows UWP
@@ -82,4 +81,4 @@ Used Operating system:
<!--- End of this issue -->
*note: Once the issue is made we require you to update it with new information or Kodi versions should that be required.
-Team Kodi will consider your problem report however, we will not make any promises the problem will be solved.* \ No newline at end of file
+Team Kodi will consider your problem report however, we will not make any promises the problem will be solved.*
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 0dc08a7caf..e8b2c85d81 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -71,7 +71,6 @@ Used Operating system:
- [ ] iOS
- [ ] Linux
- [ ] OSX
- - [ ] Raspberry-Pi
- [ ] Windows
- [ ] Windows UWP
diff --git a/.gitignore b/.gitignore
index 608d40673d..0d9778728d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,8 @@ CMakeSettings.json
# Windows specific generated files
*.appx
+*.appxsym
+*.msix
*.cer
*.exp
*.ilk
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index c684e01095..6beae9269e 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -9037,29 +9037,7 @@ msgctxt "#16329"
msgid "VAAPI - Motion compensated"
msgstr ""
-#. Description of OSD video settings for deinterlace method with label #16330
-#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
-msgctxt "#16330"
-msgid "MMAL - Advanced"
-msgstr ""
-
-#. Description of OSD video settings for deinterlace method with label #16331
-#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
-msgctxt "#16331"
-msgid "MMAL - Advanced (half)"
-msgstr ""
-
-#. Description of OSD video settings for deinterlace method with label #16332
-#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
-msgctxt "#16332"
-msgid "MMAL - Bob"
-msgstr ""
-
-#. Description of OSD video settings for deinterlace method with label #16333
-#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
-msgctxt "#16333"
-msgid "MMAL - Bob (half)"
-msgstr ""
+#empty strings from id 16330 to 16333
#. Description of OSD video settings for deinterlace method with label #16334
#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
@@ -15134,7 +15112,12 @@ msgctxt "#24048"
msgid "VideoPlayer InputStream"
msgstr ""
-#empty string with id 24049
+#. To show addon as deprecated over icon
+#: addons/skin.estuary/xml/AddonBrowser.xml
+#: addons/skin.estuary/xml/DialogAddonInfo.xml
+msgctxt "#24049"
+msgid "Add-on has been marked deprecated in repository."
+msgstr ""
#: unknown
msgctxt "#24050"
@@ -15377,6 +15360,8 @@ msgctxt "#24095"
msgid "Local package cache"
msgstr ""
+#. To show addon as broken over icon
+#: addons/skin.estuary/xml/AddonBrowser.xml
#: addons/skin.estuary/xml/DialogAddonInfo.xml
msgctxt "#24096"
msgid "Add-on has been marked broken in repository."
@@ -15515,7 +15500,7 @@ msgstr ""
#. Button in Add-on Manager -> Available Updates for updating all add-ons when auto-updating is off.
#: xbmc/filesystem/AddonDirectory.cpp
msgctxt "#24122"
-msgid "Update all"
+msgid "Install all updates"
msgstr ""
#. Description of setting with label #24105 "Pause when searching for subtitles"
@@ -15592,7 +15577,13 @@ msgctxt "#24136"
msgid "Would you like to enable this add-on?"
msgstr ""
-#empty strings from id 24137 to 24138
+#. Button in Add-on Manager -> Available Updates for updating all possible add-ons when auto-updating is off.
+#: xbmc/filesystem/AddonDirectory.cpp
+msgctxt "#24137"
+msgid "Install auto updates only"
+msgstr ""
+
+#empty strings from id 24138 to 24138
#. Label for the action provided by addon management events to jump to a specific Add-on
#: xbmc/events/AddonManagementEvent.cpp
@@ -15731,7 +15722,67 @@ msgctxt "#24163"
msgid "Match Apple tvOS Standard (Siri remote)"
msgstr ""
-#empty strings from id 24164 to 24990
+#. Header text for yes/no dialog about enable of broken addon
+#: xbmc/addons/gui/GUIHelpers.cpp
+msgctxt "#24164"
+msgid "Addon \"{0:s}\" broken"
+msgstr ""
+
+#. Yes/no dialog text with addon broken string value and to ask for use
+#: xbmc/addons/gui/GUIHelpers.cpp
+msgctxt "#24165"
+msgid "Addon marked as broken with following note:[CR][B][I]{0:s}[/I][/B][CR][CR]Do you want to enable?"
+msgstr ""
+
+#. Header text for yes/no dialog about enable of deprecated addon
+#: xbmc/addons/gui/GUIHelpers.cpp
+msgctxt "#24166"
+msgid "Addon \"{0:s}\" deprecated"
+msgstr ""
+
+#. Yes/no dialog text with addon deprecated string value and to ask for use
+#: xbmc/addons/gui/GUIHelpers.cpp
+msgctxt "#24167"
+msgid "Addon marked as deprecated with following note:[CR][B][I]{0:s}[/I][/B][CR][CR]Do you want to enable?"
+msgstr ""
+
+#. Notification event to show addon marked as deprecated.
+#: xbmc/addons/AddonInstaller.cpp
+msgctxt "#24168"
+msgid "Deprecated: {0:s}"
+msgstr ""
+
+#. Lifecycle state name, for normal addons (no special). Used also on skin to compare and identify related state.
+#: addons/skin.estuary/xml/AddonBrowser.xml
+#: addons/skin.estuary/xml/DialogAddonInfo.xml
+#: addons/skin.estuary/xml/Variables.xml
+#: xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
+msgctxt "#24169"
+msgid "Normal"
+msgstr ""
+
+#. Lifecycle state name, for deprecated addons. Used also on skin to compare and identify related state.
+#: addons/skin.estuary/xml/AddonBrowser.xml
+#: addons/skin.estuary/xml/DialogAddonInfo.xml
+#: addons/skin.estuary/xml/Variables.xml
+#: xbmc/filesystem/AddonsDirectory.cpp
+#: xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
+msgctxt "#24170"
+msgid "Deprecated"
+msgstr ""
+
+#. Lifecycle state name, for broken and not usable addons. Used also on skin to compare and identify related state.
+#: addons/skin.estuary/xml/AddonBrowser.xml
+#: addons/skin.estuary/xml/DialogAddonInfo.xml
+#: addons/skin.estuary/xml/Variables.xml
+#: xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
+msgctxt "#24171"
+msgid "Broken"
+msgstr ""
+
+#24171-24179 reserved for future use of lifecycle state name (to have continuous chain of GUI)
+
+#empty strings from id 24180 to 24990
#. Used as error message in add-on browser when add-on repository data could not be downloaded
#: xbmc/filesystem/AddonsDirectory.cpp
@@ -20100,17 +20151,7 @@ msgctxt "#36433"
msgid "When enabled, VAAPI render method is preferred and the CPU has less load. If you experience hangs, disable this option."
msgstr ""
-#. Description of setting "Enable MMAL hardware decoding of video files"
-#: system/settings/settings.xml
-msgctxt "#36434"
-msgid "Allow hardware acceleration - MMAL"
-msgstr ""
-
-#. Description of setting "Enable MMAL hardware decoding of video files"
-#: system/settings/settings.xml
-msgctxt "#36435"
-msgid "Use VideoPlayer for decoding of video files with MMAL acceleration."
-msgstr ""
+#empty strings from id 36434 to 36435
#. Description for setting #310: "Keyboard layouts"
#: system/settings/settings.xml
@@ -20355,15 +20396,7 @@ msgctxt "#36541"
msgid "Allows volume control from AirPlay clients."
msgstr ""
-#: system/settings/rbp.xml
-msgctxt "#36542"
-msgid "Output to both analogue (headphones) and HDMI"
-msgstr ""
-
-#: system/settings/rbp.xml
-msgctxt "#36543"
-msgid "Enable this to make dialogue louder compared to background sounds when downmixing multichannel audio"
-msgstr ""
+#empty strings from id 36542 to 36543
#: system/settings/settings.xml
msgctxt "#36544"
@@ -20382,12 +20415,10 @@ msgctxt "#36546"
msgid "Sets the visual depth of subtitles for stereoscopic 3D videos. The higher the value, the closer the subtitles will appear to the viewer."
msgstr ""
-#: system/settings/rbp.xml
-msgctxt "#36547"
-msgid "Use higher quality textures for covers and fanart (uses more memory)"
-msgstr ""
+#empty string with id 36547
-#: system/settings/rbp.xml
+#. Description of setting with label #37021 "Set GUI resolution limit"
+#: system/settings/android.xml
#: system/settings/gbm.xml
msgctxt "#36548"
msgid "Limits resolution of GUI to save memory. Does not affect video playback. Requires restart."
@@ -21024,24 +21055,9 @@ msgctxt "#37016"
msgid "Select this option if your receiver is capable of decoding Dolby Digital Plus (E-AC3) streams."
msgstr ""
-#: system/settings/rbp.xml
-msgctxt "#37017"
-msgid "Dual audio output"
-msgstr ""
+#empty strings from id 37017 to 37020
-#: system/settings/rbp.xml
-msgctxt "#37018"
-msgid "Boost centre channel when downmixing"
-msgstr ""
-
-#empty string with id 37019
-
-#: system/settings/rbp.xml
-msgctxt "#37020"
-msgid "Enable higher colour depth artwork"
-msgstr ""
-
-#: system/settings/rbp.xml
+#: system/settings/android.xml
#: system/settings/gbm.xml
msgctxt "#37021"
msgid "Set GUI resolution limit"
@@ -21057,40 +21073,34 @@ msgctxt "#37023"
msgid "Do you wish to stop playback on the remote device?"
msgstr ""
-#: system/settings/rbp.xml
-msgctxt "#37024"
-msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1 (AC3), this allows multichannel audio such as AAC 5.1 or FLAC 5.1 to be listened to in 5.1 surround sound. Note: Not recommended on Pi as this requires a lot of CPU."
-msgstr ""
+#empty string id 37024
#: system/settings/settings.xml
msgctxt "#37025"
msgid "Configure audio encoder settings such as quality and compression level"
msgstr ""
-#: system/settings/rbp.xml
#: system/settings/android.xml
msgctxt "#37026"
msgid "Auto"
msgstr ""
-#: system/settings/rbp.xml
+#: system/settings/android.xml
msgctxt "#37027"
msgid "540"
msgstr ""
-#: system/settings/rbp.xml
#: system/settings/android.xml
#: system/settings/gbm.xml
msgctxt "#37028"
msgid "720"
msgstr ""
-#: system/settings/rbp.xml
+#: system/settings/android.xml
msgctxt "#37029"
msgid "900"
msgstr ""
-#: system/settings/rbp.xml
#: system/settings/android.xml
#: system/settings/gbm.xml
msgctxt "#37030"
@@ -21193,12 +21203,7 @@ msgctxt "#37046"
msgid "1080"
msgstr ""
-#empty strings from id 37047 to 38009
-
-#: system/settings/rbp.xml
-msgctxt "#38010"
-msgid "GPU accelerated"
-msgstr ""
+#empty strings from id 37047 to 38010
#. Setting #38011 "Show All Items entry"
#: system/settings/settings.xml
@@ -21279,27 +21284,7 @@ msgctxt "#38026"
msgid "Appearances"
msgstr ""
-#: system/settings/rbp.xml
-msgctxt "#38027"
-msgid "Decode the stereo stream from 3D files"
-msgstr ""
-
-#. Description of setting with label #38027 "Decode the stereo stream from 3D files"
-#: system/settings/rbp.xml
-msgctxt "#38028"
-msgid "If enabled, videos created in Multiview Video Coding (MVC) format can also be watched in stereoscopic 3D. MVC format is typically found on 3D Blu-rays.[CR]Note: Processing of this data may reduce playback performance, so only enable if you require stereoscopic 3D support."
-msgstr ""
-
-#: system/settings/rbp.xml
-msgctxt "#38029"
-msgid "Enable Full HD HDMI modes for stereoscopic 3D"
-msgstr ""
-
-#. Description of setting "Enable Full HD HDMI modes for stereoscopic 3D" with label #38029
-#: system/settings/rbp.xml
-msgctxt "#38030"
-msgid "This option uses frame-packing to output full resolution for 3D through HDMI.[CR]Enabling this improves quality of Multiview Video Coding (MVC) videos, but may not be supported by all displays."
-msgstr ""
+#empty strings from id 38027 to 38030
#. Label for an option to select the video stream to play if current video has more than one video stream
#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
@@ -22154,3 +22139,7 @@ msgctxt "#39119"
msgid "Last modified"
msgstr ""
+#: xbmc/settings/dialogs/GUIDialogContentSettings.cpp
+msgctxt "#39120"
+msgid "Skip filename matching for external audio tracks"
+msgstr ""
diff --git a/addons/skin.estouchy/addon.xml b/addons/skin.estouchy/addon.xml
index 90d37a7cff..8fd9faed93 100644
--- a/addons/skin.estouchy/addon.xml
+++ b/addons/skin.estouchy/addon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<addon id="skin.estouchy" version="3.0.2" name="Estouchy" provider-name="Team Kodi">
+<addon id="skin.estouchy" version="3.0.3" name="Estouchy" provider-name="Team Kodi">
<requires>
<import addon="xbmc.gui" version="5.15.0"/>
</requires>
diff --git a/addons/skin.estouchy/changelog.txt b/addons/skin.estouchy/changelog.txt
index 17636e74ee..97d21c3578 100644
--- a/addons/skin.estouchy/changelog.txt
+++ b/addons/skin.estouchy/changelog.txt
@@ -1,3 +1,16 @@
+V3.0.3
+- Add chapter indicators to the progress bar
+- Add sort method / sort order / Channel group options to the PVR sections
+- Larger progress and volume bar
+
+V3.0.2
+- Updated language files from Transifex
+
+V3.0.1
+- Updated language files from Transifex
+
+V3.0.0
+- Kodi v19 Matrix
V2.0.0
- Kodi v18 Leia
diff --git a/addons/skin.estouchy/xml/CustomVolume.xml b/addons/skin.estouchy/xml/CustomVolume.xml
index 4a94a1a8e8..65176fd712 100644
--- a/addons/skin.estouchy/xml/CustomVolume.xml
+++ b/addons/skin.estouchy/xml/CustomVolume.xml
@@ -14,17 +14,15 @@
<visible>![Window.IsVisible(Notification) | Window.IsVisible(VolumeBar) | Window.IsVisible(SeekBar)]</visible>
</control>
<control type="group">
- <posx>430</posx>
- <posy>0</posy>
- <width>420</width>
- <height>78</height>
+ <posx>364</posx>
+ <posy>10</posy>
<include>16x9_xPos_Relocation</include>
<visible>![Window.IsVisible(Notification) | Window.IsVisible(VolumeBar) | Window.IsVisible(SeekBar)]</visible>
<control type="label">
<description>label</description>
- <posx>20</posx>
- <posy>10</posy>
- <height>58</height>
+ <posx>0</posx>
+ <posy>0</posy>
+ <height>32</height>
<width>400</width>
<label>13376</label>
<font>font20_title</font>
@@ -32,10 +30,10 @@
</control>
<control type="label">
<description>Volumelabel</description>
- <posx>400</posx>
- <posy>10</posy>
- <height>58</height>
- <width>400</width>
+ <posx>552</posx>
+ <posy>0</posy>
+ <width>180</width>
+ <height>32</height>
<label>$INFO[Control.GetLabel(1)]</label>
<font>font20_title</font>
<align>right</align>
@@ -44,9 +42,9 @@
<control type="progress" id="2">
<description>Volume</description>
<posx>0</posx>
- <posy>68</posy>
- <width>420</width>
- <height>10</height>
+ <posy>34</posy>
+ <width>552</width>
+ <height>24</height>
<texturebg colordiffuse="grey3">white.png</texturebg>
<midtexture colordiffuse="blue">white.png</midtexture>
<info>Player.Volume</info>
@@ -54,9 +52,9 @@
<control type="slider" id="1">
<description>Volume Slider</description>
<posx>0</posx>
- <posy>10</posy>
- <width>420</width>
- <height>80</height>
+ <posy>30</posy>
+ <width>552</width>
+ <height>32</height>
<info>Player.Volume</info>
<action>Volume</action>
<texturesliderbar></texturesliderbar>
diff --git a/addons/skin.estouchy/xml/DialogAddonInfo.xml b/addons/skin.estouchy/xml/DialogAddonInfo.xml
index c78fc7f52d..44b7d3c573 100644
--- a/addons/skin.estouchy/xml/DialogAddonInfo.xml
+++ b/addons/skin.estouchy/xml/DialogAddonInfo.xml
@@ -193,7 +193,7 @@
<aligny>center</aligny>
<font>font20_title</font>
<textcolor>selected</textcolor>
- <visible>String.IsEmpty(ListItem.AddonBroken)</visible>
+ <visible>String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24169])</visible>
</control>
<control type="textbox">
<description>Disclaimer</description>
@@ -205,7 +205,7 @@
<label fallback="231">$INFO[ListItem.AddonDisclaimer]</label>
<textcolor>selected</textcolor>
<autoscroll time="2000" delay="3000" repeat="5000">true</autoscroll>
- <visible>String.IsEmpty(ListItem.AddonBroken)</visible>
+ <visible>String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24169])</visible>
</control>
<control type="label">
<description>Broken label</description>
@@ -214,11 +214,24 @@
<width>200</width>
<height>25</height>
<font>font20_title</font>
- <label>$LOCALIZE[24098]:</label>
+ <label>$LOCALIZE[24171]:</label>
<align>right</align>
<aligny>center</aligny>
<textcolor>selected</textcolor>
- <visible>!String.IsEmpty(ListItem.AddonBroken)</visible>
+ <visible>String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24171])</visible>
+ </control>
+ <control type="label">
+ <description>Deprecated label</description>
+ <posx>200</posx>
+ <posy>120</posy>
+ <width>200</width>
+ <height>25</height>
+ <font>font20_title</font>
+ <label>$LOCALIZE[24170]:</label>
+ <align>right</align>
+ <aligny>center</aligny>
+ <textcolor>selected</textcolor>
+ <visible>String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24170])</visible>
</control>
<control type="textbox">
<description>Reason label</description>
@@ -227,12 +240,11 @@
<width>730</width>
<height>50</height>
<font>font20</font>
- <label>$INFO[ListItem.Addonbroken]</label>
+ <label>$INFO[ListItem.AddonLifecycleDesc]</label>
<align>left</align>
- <aligny>center</aligny>
<textcolor>selected</textcolor>
<autoscroll time="2000" delay="3000" repeat="5000">true</autoscroll>
- <visible>!String.IsEmpty(ListItem.AddonBroken)</visible>
+ <visible>String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24170]) | String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24171])</visible>
</control>
</control>
</control>
@@ -275,6 +287,7 @@
<align>left</align>
<include>ButtonInfoDialogsCommonValues</include>
<label>21340</label>
+ <textwidth>150</textwidth>
</control>
<control type="button" id="12">
<description>Changelog button</description>
diff --git a/addons/skin.estouchy/xml/DialogPVRInfo.xml b/addons/skin.estouchy/xml/DialogPVRInfo.xml
index 897595647f..aafa2f920e 100644
--- a/addons/skin.estouchy/xml/DialogPVRInfo.xml
+++ b/addons/skin.estouchy/xml/DialogPVRInfo.xml
@@ -213,11 +213,11 @@
<label>19003</label>
<visible>Window.IsActive(PVRGuideInfo) | Window.IsActive(PVRRecordingInfo)</visible>
</control>
- <control type="button" id="7">
- <description>OK</description>
+ <control type="button" id="11">
+ <description>Reminders</description>
<width>230</width>
<include>ButtonInfoDialogsCommonValues</include>
- <label>186</label>
+ <label>826</label>
</control>
</control>
</controls>
diff --git a/addons/skin.estouchy/xml/DialogVolumeBar.xml b/addons/skin.estouchy/xml/DialogVolumeBar.xml
index 8da9fd21c0..bd8c8c0e9d 100644
--- a/addons/skin.estouchy/xml/DialogVolumeBar.xml
+++ b/addons/skin.estouchy/xml/DialogVolumeBar.xml
@@ -3,28 +3,26 @@
<include>dialogeffect</include>
<controls>
<control type="group">
- <posx>390</posx>
- <posy>0</posy>
- <width>500</width>
- <height>78</height>
+ <posx>364</posx>
+ <posy>10</posy>
<include>16x9_xPos_Relocation</include>
<visible>![Window.IsVisible(Notification)]</visible>
<control type="label">
<description>label</description>
<posx>0</posx>
- <posy>10</posy>
- <height>58</height>
- <width>500</width>
+ <posy>0</posy>
+ <height>32</height>
+ <width>400</width>
<label>13376</label>
<font>font20_title</font>
<aligny>center</aligny>
</control>
<control type="label">
<description>Volumelabel</description>
- <posx>500</posx>
- <posy>10</posy>
- <height>58</height>
- <width>500</width>
+ <posx>552</posx>
+ <posy>0</posy>
+ <width>180</width>
+ <height>32</height>
<label>$INFO[Control.GetLabel(1)]</label>
<font>font20_title</font>
<align>right</align>
@@ -33,9 +31,9 @@
<control type="progress" id="2">
<description>Volume</description>
<posx>0</posx>
- <posy>72</posy>
- <width>500</width>
- <height>6</height>
+ <posy>34</posy>
+ <width>552</width>
+ <height>24</height>
<texturebg colordiffuse="grey3">white.png</texturebg>
<midtexture colordiffuse="blue">white.png</midtexture>
<info>Player.Volume</info>
@@ -43,9 +41,9 @@
<control type="slider" id="1">
<description>Volume Slider</description>
<posx>0</posx>
- <posy>72</posy>
- <width>500</width>
- <height>6</height>
+ <posy>30</posy>
+ <width>552</width>
+ <height>32</height>
<info>Player.Volume</info>
<texturesliderbar></texturesliderbar>
<textureslidernib></textureslidernib>
diff --git a/addons/skin.estouchy/xml/Includes.xml b/addons/skin.estouchy/xml/Includes.xml
index bdf8f64b3b..52c036bd01 100644
--- a/addons/skin.estouchy/xml/Includes.xml
+++ b/addons/skin.estouchy/xml/Includes.xml
@@ -16,6 +16,7 @@
</variable>
<variable name="OSDImage">
<value condition="Window.IsVisible(MusicOSD)">$INFO[MusicPlayer.Cover]</value>
+ <value condition="Window.IsVisible(VideoOSD) + !String.IsEmpty(Player.Art(poster))">$INFO[Player.Art(poster)]</value>
<value condition="Window.IsVisible(VideoOSD)">$INFO[VideoPlayer.Cover]</value>
</variable>
<variable name="OSDLabel1">
@@ -410,6 +411,13 @@
<visible>![Window.IsVisible(TVChannels) | Window.IsVisible(RadioChannels) | Window.IsVisible(TVGuide) | Window.IsVisible(RadioGuide) | Window.IsVisible(TVRecordings) | Window.IsVisible(RadioRecordings) | Window.IsVisible(TVTimers) | Window.IsVisible(RadioTimers) | Window.IsVisible(TVTimerRules) | Window.IsVisible(RadioTimerRules) | Window.IsVisible(TVSearch) | Window.IsVisible(RadioSearch) | Window.IsVisible(MusicOSD) | Window.IsVisible(VideoOSD) | Window.IsVisible(MusicPlaylist) | Window.IsVisible(VideoPlaylist) | Window.IsVisible(MusicPlaylistEditor)]</visible>
</item>
<item>
+ <label>31202</label>
+ <onclick condition="String.IsEmpty(Window(Home).Property(ViewMenuVisible))">SetProperty(ViewMenuVisible,Show,Home)</onclick>
+ <onclick condition="!String.IsEmpty(Window(Home).Property(ViewMenuVisible))">ClearProperty(ViewMenuVisible,Home)</onclick>
+ <icon>icon_button_view.png</icon>
+ <visible>Window.IsVisible(TVChannels) | Window.IsVisible(RadioChannels) | Window.IsVisible(TVGuide) | Window.IsVisible(RadioGuide) | Window.IsVisible(TVRecordings) | Window.IsVisible(RadioRecordings) | Window.IsVisible(TVTimers) | Window.IsVisible(RadioTimers) | Window.IsVisible(TVTimerRules) | Window.IsVisible(RadioTimerRules) | Window.IsVisible(TVSearch) | Window.IsVisible(RadioSearch)</visible>
+ </item>
+ <item>
<label>5</label>
<onclick condition="String.IsEmpty(Window(Home).Property(PopupMenuVisible))">SetProperty(PopupMenuVisible,Show,Home)</onclick>
<onclick condition="!String.IsEmpty(Window(Home).Property(PopupMenuVisible))">ClearProperty(PopupMenuVisible,Home)</onclick>
@@ -951,6 +959,55 @@
<align>center</align>
<aligny>center</aligny>
</include>
+ <include name="ViewMenu">
+ <control type="group">
+ <visible>!String.IsEmpty(Window(Home).Property(ViewMenuVisible))</visible>
+ <include>VisibleFadeEffect</include>
+ <animation effect="fade" time="250">WindowClose</animation>
+ <control type="button">
+ <description>Hidden button to close the sort when its focused</description>
+ <posx>0</posx>
+ <posy>0</posy>
+ <include>ScreenWidth</include>
+ <height>960</height>
+ <texturenofocus></texturenofocus>
+ <texturefocus></texturefocus>
+ <onclick>ClearProperty(ViewMenuVisible,Home)</onclick>
+ </control>
+ <control type="group">
+ <posx>360r</posx>
+ <posy>685r</posy>
+ <control type="image">
+ <description>Panel image</description>
+ <posx>0</posx>
+ <posy>$PARAM[panel-posy]</posy>
+ <width>350</width>
+ <height>$PARAM[panel-height]</height>
+ <texture>dialog_back.png</texture>
+ </control>
+ <control type="grouplist">
+ <posx>0</posx>
+ <posy>$PARAM[panel-posy]</posy>
+ <width>350</width>
+ <height>640</height>
+ <onleft>9000</onleft>
+ <onright>50</onright>
+ <onup>9000</onup>
+ <ondown>9000</ondown>
+ <itemgap>0</itemgap>
+ <include condition="Window.IsVisible(TVChannels) | Window.IsVisible(RadioChannels) | Window.IsVisible(TVGuide) | Window.IsVisible(RadioGuide) | Window.IsVisible(TVRecordings) | Window.IsVisible(RadioRecordings) | Window.IsVisible(TVTimers) | Window.IsVisible(RadioTimers) | Window.IsVisible(TVTimerRules) | Window.IsVisible(RadioTimerRules) | Window.IsVisible(TVSearch) | Window.IsVisible(RadioSearch)">PVRViews</include>
+ </control>
+ <control type="image">
+ <description>Panel Arrow image</description>
+ <posx>225r</posx>
+ <posy>122r</posy>
+ <width>75</width>
+ <height>41</height>
+ <texture>arrow_up.png</texture>
+ </control>
+ </control>
+ </control>
+ </include>
<include name="PopupMenu">
<control type="group">
<visible>!String.IsEmpty(Window(Home).Property(PopupMenuVisible))</visible>
@@ -1438,7 +1495,7 @@
<colordiffuse>blue</colordiffuse>
</control>
</include>
- <include name="PVRMenu">
+ <include name="PVRViews">
<control type="button" id="201">
<include>MenuButtonCommonValues</include>
<label>19019</label>
@@ -1496,6 +1553,55 @@
<visible>Window.IsVisible(TVRecordings) | Window.IsVisible(RadioRecordings)</visible>
</control>
</include>
+ <include name="PVRMenu">
+ <control type="button" id="28">
+ <description>Group button</description>
+ <include>MenuButtonCommonValues</include>
+ <label>19141</label>
+ <visible>Window.IsActive(MyPVRChannels.xml) | Window.IsActive(MyPVRGuide.xml)</visible>
+ </control>
+ <control type="button" id="3">
+ <description>Sort by button</description>
+ <include>MenuButtonCommonValues</include>
+ <label>103</label>
+ </control>
+ <control type="togglebutton" id="4">
+ <description>Sort asc</description>
+ <include>MenuButtonCommonValues</include>
+ <alttexturefocus>list_focus.png</alttexturefocus>
+ <alttexturenofocus></alttexturenofocus>
+ <label>31051</label>
+ <altlabel>31050</altlabel>
+ <usealttexture>Container.SortDirection(Ascending)</usealttexture>
+ </control>
+ <control type="button" id="10">
+ <description>Watched button</description>
+ <include>MenuButtonCommonValues</include>
+ <label>20367</label>
+ <visible>Window.IsActive(MyPVRRecordings.xml)</visible>
+ </control>
+ <control type="radiobutton" id="5">
+ <description>Group items Toggle</description>
+ <textwidth>240</textwidth>
+ <include>MenuButtonCommonValues</include>
+ <label>19270</label>
+ <visible>Window.IsActive(MyPVRRecordings.xml)</visible>
+ </control>
+ <control type="radiobutton" id="7">
+ <description>Deleted items Toggle</description>
+ <textwidth>240</textwidth>
+ <include>MenuButtonCommonValues</include>
+ <label>19184</label>
+ <visible>Window.IsActive(MyPVRRecordings.xml)</visible>
+ </control>
+ <control type="radiobutton" id="8">
+ <description>Hide disabled items Toggle</description>
+ <textwidth>240</textwidth>
+ <include>MenuButtonCommonValues</include>
+ <label>19077</label>
+ <visible>Window.IsActive(MyPVRTimers.xml)</visible>
+ </control>
+ </include>
<include name="SettingsContent">
<control type="image">
<posx>390</posx>
diff --git a/addons/skin.estouchy/xml/IncludesPlayerControls.xml b/addons/skin.estouchy/xml/IncludesPlayerControls.xml
index 589379f087..7aa98cab65 100644
--- a/addons/skin.estouchy/xml/IncludesPlayerControls.xml
+++ b/addons/skin.estouchy/xml/IncludesPlayerControls.xml
@@ -84,9 +84,9 @@
<control type="progress">
<description>Progressbar</description>
<posx>0</posx>
- <posy>40</posy>
+ <posy>34</posy>
<width>552</width>
- <height>12</height>
+ <height>24</height>
<info>Player.ProgressCache</info>
<midtexture colordiffuse="grey2">white.png</midtexture>
<texturebg colordiffuse="grey3">white.png</texturebg>
@@ -94,12 +94,21 @@
<control type="progress">
<description>Progressbar</description>
<posx>0</posx>
- <posy>40</posy>
+ <posy>34</posy>
<width>552</width>
- <height>12</height>
+ <height>24</height>
<info>Player.Progress</info>
<texturebg colordiffuse="002C2C2C">white.png</texturebg>
</control>
+ <control type="ranges">
+ <description>Chapters</description>
+ <posx>0</posx>
+ <posy>50</posy>
+ <width>552</width>
+ <height>8</height>
+ <info>Player.Chapters</info>
+ <righttexture>white.png</righttexture>
+ </control>
<control type="slider" id="87">
<description>Seek Slider</description>
<posx>0</posx>
diff --git a/addons/skin.estouchy/xml/MyPVRChannels.xml b/addons/skin.estouchy/xml/MyPVRChannels.xml
index 1197c295bf..59025e4cc1 100644
--- a/addons/skin.estouchy/xml/MyPVRChannels.xml
+++ b/addons/skin.estouchy/xml/MyPVRChannels.xml
@@ -3,6 +3,7 @@
<defaultcontrol always="true">50</defaultcontrol>
<views>50</views>
<onunload>ClearProperty(PopupMenuVisible,Home)</onunload>
+ <onunload>ClearProperty(ViewMenuVisible,Home)</onunload>
<controls>
<include>CommonBackground</include>
<include>SideMenu</include>
@@ -46,6 +47,10 @@
</control>
<include>ScrollBarCommons</include>
<include>BottomMenu</include>
+ <include content="ViewMenu">
+ <param name="panel-posy">-80</param>
+ <param name="panel-height">640</param>
+ </include>
<include content="PopupMenu">
<param name="panel-posy">-80</param>
<param name="panel-height">640</param>
diff --git a/addons/skin.estouchy/xml/MyPVRGuide.xml b/addons/skin.estouchy/xml/MyPVRGuide.xml
index 2a64ceaf65..e09815ec75 100644
--- a/addons/skin.estouchy/xml/MyPVRGuide.xml
+++ b/addons/skin.estouchy/xml/MyPVRGuide.xml
@@ -3,6 +3,7 @@
<defaultcontrol always="true">10</defaultcontrol>
<views>10</views>
<onunload>ClearProperty(PopupMenuVisible,Home)</onunload>
+ <onunload>ClearProperty(ViewMenuVisible,Home)</onunload>
<controls>
<include>CommonBackground</include>
<include>SideMenu</include>
@@ -39,6 +40,10 @@
</control>
<include>ScrollBarCommons</include>
<include>BottomMenu</include>
+ <include content="ViewMenu">
+ <param name="panel-posy">-80</param>
+ <param name="panel-height">640</param>
+ </include>
<include content="PopupMenu">
<param name="panel-posy">0</param>
<param name="panel-height">560</param>
diff --git a/addons/skin.estouchy/xml/MyPVRRecordings.xml b/addons/skin.estouchy/xml/MyPVRRecordings.xml
index 0fb79048c3..75a69ec2af 100644
--- a/addons/skin.estouchy/xml/MyPVRRecordings.xml
+++ b/addons/skin.estouchy/xml/MyPVRRecordings.xml
@@ -3,6 +3,7 @@
<defaultcontrol always="true">50</defaultcontrol>
<views>50</views>
<onunload>ClearProperty(PopupMenuVisible,Home)</onunload>
+ <onunload>ClearProperty(ViewMenuVisible,Home)</onunload>
<controls>
<include>CommonBackground</include>
<include>SideMenu</include>
@@ -43,6 +44,10 @@
</control>
<include>ScrollBarCommons</include>
<include>BottomMenu</include>
+ <include content="ViewMenu">
+ <param name="panel-posy">-80</param>
+ <param name="panel-height">640</param>
+ </include>
<include content="PopupMenu">
<param name="panel-posy">-80</param>
<param name="panel-height">640</param>
diff --git a/addons/skin.estouchy/xml/MyPVRSearch.xml b/addons/skin.estouchy/xml/MyPVRSearch.xml
index 5c792473ad..350c30f984 100644
--- a/addons/skin.estouchy/xml/MyPVRSearch.xml
+++ b/addons/skin.estouchy/xml/MyPVRSearch.xml
@@ -3,6 +3,7 @@
<defaultcontrol always="true">50</defaultcontrol>
<views>50</views>
<onunload>ClearProperty(PopupMenuVisible,Home)</onunload>
+ <onunload>ClearProperty(ViewMenuVisible,Home)</onunload>
<controls>
<include>CommonBackground</include>
<include>SideMenu</include>
@@ -43,6 +44,10 @@
</control>
<include>ScrollBarCommons</include>
<include>BottomMenu</include>
+ <include content="ViewMenu">
+ <param name="panel-posy">-80</param>
+ <param name="panel-height">640</param>
+ </include>
<include content="PopupMenu">
<param name="panel-posy">0</param>
<param name="panel-height">560</param>
diff --git a/addons/skin.estouchy/xml/MyPVRTimers.xml b/addons/skin.estouchy/xml/MyPVRTimers.xml
index b4279f0eb0..c3fc1d7d5e 100644
--- a/addons/skin.estouchy/xml/MyPVRTimers.xml
+++ b/addons/skin.estouchy/xml/MyPVRTimers.xml
@@ -3,6 +3,7 @@
<defaultcontrol always="true">50</defaultcontrol>
<views>50</views>
<onunload>ClearProperty(PopupMenuVisible,Home)</onunload>
+ <onunload>ClearProperty(ViewMenuVisible,Home)</onunload>
<controls>
<include>CommonBackground</include>
<include>SideMenu</include>
@@ -43,6 +44,10 @@
</control>
<include>ScrollBarCommons</include>
<include>BottomMenu</include>
+ <include content="ViewMenu">
+ <param name="panel-posy">-80</param>
+ <param name="panel-height">640</param>
+ </include>
<include content="PopupMenu">
<param name="panel-posy">0</param>
<param name="panel-height">560</param>
diff --git a/addons/skin.estouchy/xml/ViewsWide.xml b/addons/skin.estouchy/xml/ViewsWide.xml
index 02a800d420..c8b0e2610f 100644
--- a/addons/skin.estouchy/xml/ViewsWide.xml
+++ b/addons/skin.estouchy/xml/ViewsWide.xml
@@ -730,7 +730,7 @@
<posy>45</posy>
<width>840</width>
<height>20</height>
- <font>font20</font>
+ <font>font24</font>
<selectedcolor>selected</selectedcolor>
<align>left</align>
<aligny>center</aligny>
@@ -741,19 +741,12 @@
<posy>7</posy>
<width>870</width>
<height>30</height>
- <font>font20</font>
+ <font>font24</font>
<selectedcolor>selected</selectedcolor>
<align>right</align>
<aligny>center</aligny>
<label>$INFO[ListItem.AddonVersion]$INFO[ListItem.Property(Addon.Status), - ]</label>
</control>
- <control type="image">
- <posx>40r</posx>
- <posy>20</posy>
- <width>30</width>
- <height>30</height>
- <texture>$INFO[ListItem.Overlay]</texture>
- </control>
<control type="textbox">
<posx>250</posx>
<posy>75</posy>
@@ -761,7 +754,7 @@
<height>145</height>
<font>font25</font>
<align>justify</align>
- <label>$INFO[ListItem.AddonBroken,[COLOR=blue][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDisclaimer,[COLOR=blue][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDescription]</label>
+ <label>$INFO[ListItem.AddonLifecycleDesc,[COLOR=selected][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDisclaimer,[COLOR=blue][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDescription]</label>
</control>
</itemlayout>
<focusedlayout condition="Container.Content(Addons)" height="240" width="$PARAM[panel-width]">
@@ -796,7 +789,7 @@
<posy>45</posy>
<width>840</width>
<height>20</height>
- <font>font20</font>
+ <font>font24</font>
<selectedcolor>selected</selectedcolor>
<align>left</align>
<aligny>center</aligny>
@@ -807,19 +800,12 @@
<posy>7</posy>
<width>870</width>
<height>30</height>
- <font>font20</font>
+ <font>font24</font>
<selectedcolor>selected</selectedcolor>
<align>right</align>
<aligny>center</aligny>
<label>$INFO[ListItem.AddonVersion]$INFO[ListItem.Property(Addon.Status), - ]</label>
</control>
- <control type="image">
- <posx>40r</posx>
- <posy>20</posy>
- <width>30</width>
- <height>30</height>
- <texture>$INFO[ListItem.Overlay]</texture>
- </control>
<control type="textbox">
<posx>250</posx>
<posy>75</posy>
@@ -827,7 +813,7 @@
<height>145</height>
<font>font25</font>
<align>justify</align>
- <label>$INFO[ListItem.AddonBroken,[COLOR=blue][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDisclaimer,[COLOR=blue][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDescription]</label>
+ <label>$INFO[ListItem.AddonLifecycleDesc,[COLOR=selected][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDisclaimer,[COLOR=blue][B],[/B][/COLOR][CR]]$INFO[ListItem.AddonDescription]</label>
<autoscroll delay="2000" time="2000" repeat="2000">True</autoscroll>
</control>
</focusedlayout>
diff --git a/addons/skin.estuary/language/resource.language.en_gb/strings.po b/addons/skin.estuary/language/resource.language.en_gb/strings.po
index c86dbe1e23..d55808b8fb 100644
--- a/addons/skin.estuary/language/resource.language.en_gb/strings.po
+++ b/addons/skin.estuary/language/resource.language.en_gb/strings.po
@@ -614,7 +614,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr ""
-#empty string with id 31135
+#: /xml/DialogAddonInfo.xml
+msgctxt "#31135"
+msgid "Binary"
+msgstr ""
#: /xml/DialogAddonInfo.xml
msgctxt "#31136"
diff --git a/addons/skin.estuary/media/icons/addonstatus/enabled-broken.png b/addons/skin.estuary/media/icons/addonstatus/enabled-broken.png
new file mode 100644
index 0000000000..8b4dd1152b
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/enabled-broken.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/enabled-deprecated.png b/addons/skin.estuary/media/icons/addonstatus/enabled-deprecated.png
new file mode 100644
index 0000000000..0a8294d862
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/enabled-deprecated.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/enabled-normal.png b/addons/skin.estuary/media/icons/addonstatus/enabled-normal.png
new file mode 100644
index 0000000000..c5a89ca6f8
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/enabled-normal.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/install-pinned.png b/addons/skin.estuary/media/icons/addonstatus/install-pinned.png
new file mode 100644
index 0000000000..3c3f84f1bd
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/install-pinned.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/install.png b/addons/skin.estuary/media/icons/addonstatus/install.png
index ce396ab179..51224d5624 100644
--- a/addons/skin.estuary/media/icons/addonstatus/install.png
+++ b/addons/skin.estuary/media/icons/addonstatus/install.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/manual-pinned.png b/addons/skin.estuary/media/icons/addonstatus/manual-pinned.png
new file mode 100644
index 0000000000..1b05c15991
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/manual-pinned.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/manual.png b/addons/skin.estuary/media/icons/addonstatus/manual.png
new file mode 100644
index 0000000000..14115dd10e
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/manual.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/official-pinned.png b/addons/skin.estuary/media/icons/addonstatus/official-pinned.png
new file mode 100644
index 0000000000..0138c39c29
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/official-pinned.png
Binary files differ
diff --git a/addons/skin.estuary/media/icons/addonstatus/official.png b/addons/skin.estuary/media/icons/addonstatus/official.png
new file mode 100644
index 0000000000..f0a2033569
--- /dev/null
+++ b/addons/skin.estuary/media/icons/addonstatus/official.png
Binary files differ
diff --git a/addons/skin.estuary/xml/AddonBrowser.xml b/addons/skin.estuary/xml/AddonBrowser.xml
index 8e243175b2..62c97daddf 100644
--- a/addons/skin.estuary/xml/AddonBrowser.xml
+++ b/addons/skin.estuary/xml/AddonBrowser.xml
@@ -20,6 +20,26 @@
<include content="ListThumbInfoPanel">
<param name="fallback_image" value="DefaultAddon.png" />
</include>
+ <control type="group">
+ <visible>String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24170]) | String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24171])</visible>
+ <control type="image">
+ <left>64</left>
+ <top>109</top>
+ <width>472</width>
+ <height>472</height>
+ <texture colordiffuse="AAFFFFFF">colors/black.png</texture>
+ </control>
+ <control type="textbox">
+ <left>75</left>
+ <top>110</top>
+ <width>450</width>
+ <height>470</height>
+ <align>center</align>
+ <aligny>center</aligny>
+ <label>$VAR[AddonLifecycleType]</label>
+ <font>font32_title</font>
+ </control>
+ </control>
</control>
<include content="TopBar">
<param name="breadcrumbs_label" value="$LOCALIZE[24001]" />
diff --git a/addons/skin.estuary/xml/DialogAddonInfo.xml b/addons/skin.estuary/xml/DialogAddonInfo.xml
index 74f829b1e0..107f6babf1 100644
--- a/addons/skin.estuary/xml/DialogAddonInfo.xml
+++ b/addons/skin.estuary/xml/DialogAddonInfo.xml
@@ -15,7 +15,7 @@
<control type="button" id="5000">
<left>605</left>
<top>400</top>
- <width>1235</width>
+ <width>755</width>
<height>435</height>
<label></label>
<texturenofocus border="21">dialogs/dialog-bg.png</texturenofocus>
@@ -27,9 +27,9 @@
<enable>!String.IsEmpty(ListItem.AddonNews)</enable>
</control>
<control type="textbox">
- <left>670</left>
+ <left>650</left>
<top>430</top>
- <width>1050</width>
+ <width>665</width>
<height>375</height>
<label>$INFO[ListItem.AddonSummary,[B],[/B][CR]]$INFO[ListItem.AddonDescription][CR]$VAR[AddonNewsVar,[I][CR][CR],[/I]]</label>
<autoscroll delay="5000" repeat="7500" time="5000">true</autoscroll>
@@ -128,6 +128,107 @@
<param name="posy" value="280" />
<param name="visible" value="true" />
</include>
+ <control type="group">
+ <control type="image">
+ <left>1370</left>
+ <top>420</top>
+ <width>450</width>
+ <height>396</height>
+ <aspectratio>scale</aspectratio>
+ <texture colordiffuse="AAFFFFFF">colors/black.png</texture>
+ </control>
+ <control type="group">
+ <left>1340</left>
+ <top>430</top>
+ <control type="list">
+ <left>42</left>
+ <top>0</top>
+ <width>446</width>
+ <height>385</height>
+ <pagecontrol/>
+ <itemlayout height="75">
+ <control type="label">
+ <left>10</left>
+ <top>0</top>
+ <width>410</width>
+ <height>30</height>
+ <font>font27_narrow</font>
+ <label>$INFO[ListItem.Label,[COLOR button_focus],[/COLOR]]</label>
+ </control>
+ <control type="label">
+ <left>10</left>
+ <top>30</top>
+ <width>380</width>
+ <height>30</height>
+ <font>font27_narrow</font>
+ <label>$INFO[ListItem.Label2]</label>
+ </control>
+ <control type="image">
+ <right>25</right>
+ <top>35</top>
+ <width>32</width>
+ <height>32</height>
+ <texture>$INFO[ListItem.Icon]</texture>
+ </control>
+ </itemlayout>
+ <focusedlayout height="75">
+ <control type="label">
+ <left>10</left>
+ <top>0</top>
+ <width>410</width>
+ <height>30</height>
+ <font>font27_narrow</font>
+ <label>$INFO[ListItem.Label,[COLOR button_focus],[/COLOR]]</label>
+ <scroll>false</scroll>
+ </control>
+ <control type="label">
+ <left>10</left>
+ <top>30</top>
+ <width>380</width>
+ <height>30</height>
+ <font>font27_narrow</font>
+ <label>$INFO[ListItem.Label2]</label>
+ <scroll>false</scroll>
+ </control>
+ <control type="image">
+ <right>25</right>
+ <top>35</top>
+ <width>32</width>
+ <height>32</height>
+ <texture>$INFO[ListItem.Icon]</texture>
+ </control>
+ </focusedlayout>
+ <content>
+ <item>
+ <label>$LOCALIZE[21866]:</label>
+ <label2>$INFO[ListItem.AddonType]</label2>
+ <visible>!String.IsEmpty(ListItem.AddonType)</visible>
+ </item>
+ <item>
+ <label>$LOCALIZE[31150]:</label>
+ <label2>$INFO[ListItem.AddonOrigin]</label2>
+ <icon>$VAR[AddonsOriginVar]</icon>
+ <visible>!String.IsEmpty(ListItem.AddonOrigin)</visible>
+ </item>
+ <item>
+ <label>$LOCALIZE[22031]:</label>
+ <label2>$INFO[ListItem.AddonSize]</label2>
+ <visible>!String.IsEmpty(ListItem.AddonSize)</visible>
+ </item>
+ <item>
+ <label>$LOCALIZE[126]:</label>
+ <label2>$INFO[ListItem.Property(Addon.Status)]</label2>
+ <visible>!String.IsEmpty(ListItem.Property(Addon.Status))</visible>
+ </item>
+ <item>
+ <label>$LOCALIZE[467]:</label>
+ <label2>$LOCALIZE[31135]</label2>
+ <visible>ListItem.Property(Addon.IsBinary)</visible>
+ </item>
+ </content>
+ </control>
+ </control>
+ </control>
<control type="grouplist" id="9000">
<left>90</left>
<top>840</top>
@@ -213,7 +314,7 @@
<texture fallback="DefaultAddon.png" background="true">$INFO[ListItem.Art(thumb)]</texture>
</control>
<control type="group">
- <visible>!String.IsEmpty(ListItem.AddonBroken)</visible>
+ <visible>String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24170]) | String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24171])</visible>
<control type="image">
<left>14</left>
<top>24</top>
@@ -222,39 +323,14 @@
<texture colordiffuse="AAFFFFFF">colors/black.png</texture>
</control>
<control type="textbox">
- <left>34</left>
+ <left>25</left>
<top>24</top>
- <width>460</width>
+ <width>478</width>
<height>500</height>
<align>center</align>
<aligny>center</aligny>
- <label>$LOCALIZE[24096]</label>
- <font>font36_title</font>
- </control>
- </control>
- <control type="image">
- <left>-5</left>
- <top>525</top>
- <width>540</width>
- <height>150</height>
- <texture>dialogs/dialog-bg-nobo.png</texture>
- <bordertexture border="21">overlays/shadow.png</bordertexture>
- <bordersize>20</bordersize>
- </control>
- <control type="grouplist">
- <left>30</left>
- <top>555</top>
- <control type="label">
- <width>470</width>
- <height>40</height>
- <label>$INFO[ListItem.AddonOrigin,[COLOR button_focus]$LOCALIZE[31150]:[/COLOR] ]</label>
- <visible>!String.IsEmpty(ListItem.AddonOrigin)</visible>
- </control>
- <control type="label">
- <width>470</width>
- <height>40</height>
- <label>$INFO[ListItem.AddonSize,[COLOR button_focus]$LOCALIZE[22031]:[/COLOR] ,[CR]]</label>
- <visible>!String.IsEmpty(ListItem.AddonSize)</visible>
+ <label>$VAR[AddonLifecycleType]</label>
+ <font>font32_title</font>
</control>
</control>
</control>
diff --git a/addons/skin.estuary/xml/Includes.xml b/addons/skin.estuary/xml/Includes.xml
index 9ed40262b9..2414db4180 100644
--- a/addons/skin.estuary/xml/Includes.xml
+++ b/addons/skin.estuary/xml/Includes.xml
@@ -786,48 +786,18 @@
<animation effect="fade" start="100" end="0" time="300" condition="Window.Next(screencalibration)">WindowClose</animation>
</control>
<control type="grouplist">
- <left>35</left>
- <description>Left side of top bar</description>
<width>900</width>
- <top>-7</top>
- <height>100</height>
- <orientation>horizontal</orientation>
- <usecontrolcoords>true</usecontrolcoords>
- <animation effect="fade" start="0" end="100" time="300">WindowOpen</animation>
- <animation effect="fade" start="100" end="0" time="200">WindowClose</animation>
- <animation effect="slide" end="0,16" time="200" reversible="true" condition="String.IsEmpty(Control.GetLabel(18900))">Conditional</animation>
- <animation effect="slide" end="70,0" time="200" reversible="true" condition="Control.IsVisible(799)">Conditional</animation>
- <control type="label">
- <label>$PARAM[breadcrumbs_label]</label>
- <include>BreadcrumbsLabel</include>
- </control>
- <control type="label">
- <label>$INFO[Container.ShowTitle, / ]</label>
- <include>BreadcrumbsLabel</include>
- <visible>!String.IsEmpty(Container.ShowTitle) + !String.IsEqual(Container.ShowTitle,Container.FolderName)</visible>
- </control>
- <control type="label">
- <label>$INFO[Container.FolderName, / ]</label>
- <include>BreadcrumbsLabel</include>
- <visible>![Container.Content() + Window.IsActive(videos)]</visible>
- <visible>![Window.IsActive(MyPVRChannels.xml) | Window.IsActive(MyPVRTimers.xml) | Window.IsActive(MyPVRRecordings.xml) | Window.IsActive(MyPVRSearch.xml)]</visible>
- </control>
- <control type="label">
- <label>$INFO[Container.PluginCategory, / ]</label>
- <include>BreadcrumbsLabel</include>
- <visible>!String.isempty(Container.PluginCategory)</visible>
- </control>
- <control type="label">
- <label>$INFO[Control.GetLabel(10),: ]</label>
- <include>BreadcrumbsLabel</include>
- <visible>!String.IsEqual(Control.GetLabel(10),$LOCALIZE[16100]) + Window.IsActive(videos)</visible>
- </control>
- <control type="label">
- <left>10</left>
- <label>($LOCALIZE[31052])</label>
- <include>BreadcrumbsLabel</include>
- <visible>Container.Filtered</visible>
- </control>
+ <include content="TopBarLabels">
+ <param name="breadcrumbs_label" value="$PARAM[breadcrumbs_label]" />
+ </include>
+ <visible>Player.HasMedia</visible>
+ </control>
+ <control type="grouplist">
+ <width>1800</width>
+ <include content="TopBarLabels">
+ <param name="breadcrumbs_label" value="$PARAM[breadcrumbs_label]" />
+ </include>
+ <visible>!Player.HasMedia</visible>
</control>
<control type="button">
<top>0</top>
@@ -1006,6 +976,49 @@
<include condition="Skin.HasSetting(touchmode) + !Window.IsActive(home)">TouchBackButton</include>
</definition>
</include>
+ <include name="TopBarLabels">
+ <left>35</left>
+ <description>Left side of top bar</description>
+ <top>-7</top>
+ <height>100</height>
+ <orientation>horizontal</orientation>
+ <usecontrolcoords>true</usecontrolcoords>
+ <animation effect="fade" start="0" end="100" time="300">WindowOpen</animation>
+ <animation effect="fade" start="100" end="0" time="200">WindowClose</animation>
+ <animation effect="slide" end="0,16" time="200" reversible="true" condition="String.IsEmpty(Control.GetLabel(18900))">Conditional</animation>
+ <animation effect="slide" end="70,0" time="200" reversible="true" condition="Control.IsVisible(799)">Conditional</animation>
+ <control type="label">
+ <label>$PARAM[breadcrumbs_label]</label>
+ <include>BreadcrumbsLabel</include>
+ </control>
+ <control type="label">
+ <label>$INFO[Container.ShowTitle, / ]</label>
+ <include>BreadcrumbsLabel</include>
+ <visible>!String.IsEmpty(Container.ShowTitle) + !String.IsEqual(Container.ShowTitle,Container.FolderName)</visible>
+ </control>
+ <control type="label">
+ <label>$INFO[Container.FolderName, / ]</label>
+ <include>BreadcrumbsLabel</include>
+ <visible>![Container.Content() + Window.IsActive(videos)]</visible>
+ <visible>![Window.IsActive(MyPVRChannels.xml) | Window.IsActive(MyPVRTimers.xml) | Window.IsActive(MyPVRRecordings.xml) | Window.IsActive(MyPVRSearch.xml)]</visible>
+ </control>
+ <control type="label">
+ <label>$INFO[Container.PluginCategory, / ]</label>
+ <include>BreadcrumbsLabel</include>
+ <visible>!String.isempty(Container.PluginCategory)</visible>
+ </control>
+ <control type="label">
+ <label>$INFO[Control.GetLabel(10),: ]</label>
+ <include>BreadcrumbsLabel</include>
+ <visible>!String.IsEqual(Control.GetLabel(10),$LOCALIZE[16100]) + Window.IsActive(videos)</visible>
+ </control>
+ <control type="label">
+ <left>10</left>
+ <label>($LOCALIZE[31052])</label>
+ <include>BreadcrumbsLabel</include>
+ <visible>Container.Filtered</visible>
+ </control>
+ </include>
<include name="BreadcrumbsLabel">
<font>font45</font>
<shadowcolor>text_shadow</shadowcolor>
diff --git a/addons/skin.estuary/xml/MusicVisualisation.xml b/addons/skin.estuary/xml/MusicVisualisation.xml
index 94f5b273e8..57524bf6cf 100644
--- a/addons/skin.estuary/xml/MusicVisualisation.xml
+++ b/addons/skin.estuary/xml/MusicVisualisation.xml
@@ -127,7 +127,7 @@
<width>1450</width>
<height>40</height>
<aligny>center</aligny>
- <label>$INFO[MusicPlayer.Album]$INFO[MusicPlayer.DiscNumber, - $LOCALIZE[427] ]</label>
+ <label>$INFO[MusicPlayer.Album]$VAR[MultiDiscVar]</label>
<font>font37</font>
<shadowcolor>black</shadowcolor>
<scroll>true</scroll>
diff --git a/addons/skin.estuary/xml/SettingsCategory.xml b/addons/skin.estuary/xml/SettingsCategory.xml
index e5d4cd71e4..6ab8649c46 100644
--- a/addons/skin.estuary/xml/SettingsCategory.xml
+++ b/addons/skin.estuary/xml/SettingsCategory.xml
@@ -19,7 +19,7 @@
<include>OpenClose_Right</include>
<control type="grouplist" id="5">
<description>control area</description>
- <top>163</top>
+ <top>133</top>
<left>470</left>
<pagecontrol>60</pagecontrol>
<right>0</right>
@@ -31,7 +31,7 @@
</control>
<control type="image">
<left>470</left>
- <top>160</top>
+ <top>130</top>
<right>0</right>
<height>2</height>
<texture colordiffuse="button_focus" border="2">dialogs/separator-grey.png</texture>
@@ -89,9 +89,9 @@
<control type="grouplist" id="3">
<description>button area</description>
<left>0</left>
- <top>160</top>
+ <top>130</top>
<width>470</width>
- <height>720</height>
+ <height>810</height>
<usecontrolcoords>true</usecontrolcoords>
<onleft>5</onleft>
<onright>5</onright>
@@ -101,7 +101,7 @@
<control type="button" id="10">
<description>Default Category Button</description>
<left>0</left>
- <height>90</height>
+ <height>85</height>
<width>470</width>
<textoffsetx>40</textoffsetx>
<aligny>center</aligny>
@@ -109,34 +109,10 @@
<texturefocus colordiffuse="button_focus">lists/focus.png</texturefocus>
<texturenofocus />
</control>
- <control type="radiobutton" id="20">
- <width>470</width>
- <left>0</left>
- <bottom>110</bottom>
- <height>90</height>
- <aligny>center</aligny>
- <onclick>SettingsLevelChange</onclick>
- <textoffsetx>100</textoffsetx>
- <textoffsety>0</textoffsety>
- <texturefocus colordiffuse="button_focus">colors/white.png</texturefocus>
- <texturenofocus />
- <radioposx>40</radioposx>
- <radioposy>0</radioposy>
- <radiowidth>40</radiowidth>
- <radioheight>40</radioheight>
- <onleft>5</onleft>
- <onright>5</onright>
- <onup>3</onup>
- <ondown>3</ondown>
- <textureradioonfocus>icons/settings.png</textureradioonfocus>
- <textureradioonnofocus>icons/settings.png</textureradioonnofocus>
- <textureradioofffocus>icons/settings.png</textureradioofffocus>
- <textureradiooffnofocus>icons/settings.png</textureradiooffnofocus>
- </control>
</control>
<control type="group">
<right>0</right>
- <top>163</top>
+ <top>133</top>
<bottom>137</bottom>
<width>60</width>
<control type="scrollbar" id="60">
@@ -161,6 +137,34 @@
</include>
<include>BottomBar</include>
<control type="group">
+ <depth>DepthContentPanel</depth>
+ <include>OpenClose_Left</include>
+ <control type="radiobutton" id="20">
+ <width>470</width>
+ <left>0</left>
+ <bottom>70</bottom>
+ <height>90</height>
+ <aligny>center</aligny>
+ <onclick>SettingsLevelChange</onclick>
+ <textoffsetx>100</textoffsetx>
+ <textoffsety>0</textoffsety>
+ <texturefocus colordiffuse="button_focus">colors/white.png</texturefocus>
+ <texturenofocus />
+ <radioposx>40</radioposx>
+ <radioposy>0</radioposy>
+ <radiowidth>40</radiowidth>
+ <radioheight>40</radioheight>
+ <onleft>5</onleft>
+ <onright>5</onright>
+ <onup>3</onup>
+ <ondown>3</ondown>
+ <textureradioonfocus>icons/settings.png</textureradioonfocus>
+ <textureradioonnofocus>icons/settings.png</textureradioonnofocus>
+ <textureradioofffocus>icons/settings.png</textureradioofffocus>
+ <textureradiooffnofocus>icons/settings.png</textureradiooffnofocus>
+ </control>
+ </control>
+ <control type="group">
<include>OpenClose_Right</include>
<control type="textbox" id="6">
<description>description area</description>
diff --git a/addons/skin.estuary/xml/SettingsProfile.xml b/addons/skin.estuary/xml/SettingsProfile.xml
index c77fb611de..27c10f4eed 100644
--- a/addons/skin.estuary/xml/SettingsProfile.xml
+++ b/addons/skin.estuary/xml/SettingsProfile.xml
@@ -20,7 +20,7 @@
<include>OpenClose_Right</include>
<left>472</left>
<control type="image">
- <top>160</top>
+ <top>130</top>
<right>0</right>
<height>3</height>
<texture colordiffuse="button_focus" border="2">dialogs/separator-grey.png</texture>
@@ -32,7 +32,7 @@
<texture colordiffuse="button_focus" border="2">dialogs/separator-grey.png</texture>
</control>
<control type="panel" id="2">
- <top>163</top>
+ <top>148</top>
<left>30</left>
<visible>Container(9000).Hasfocus(2)</visible>
<right>0</right>
@@ -182,7 +182,7 @@
</include>
<control type="list" id="9000">
<left>0</left>
- <top>160</top>
+ <top>130</top>
<width>470</width>
<height>567</height>
<onleft>9100</onleft>
@@ -190,7 +190,7 @@
<onup>9000</onup>
<ondown>9000</ondown>
<scrolltime>300</scrolltime>
- <itemlayout height="90" width="470">
+ <itemlayout height="85" width="470">
<control type="label">
<left>30</left>
<right>30</right>
@@ -200,7 +200,7 @@
<aligny>center</aligny>
</control>
</itemlayout>
- <focusedlayout height="90" width="470">
+ <focusedlayout height="85" width="470">
<control type="image">
<right>0</right>
<bottom>0</bottom>
diff --git a/addons/skin.estuary/xml/SettingsSystemInfo.xml b/addons/skin.estuary/xml/SettingsSystemInfo.xml
index 787c7f3900..a0bec86593 100644
--- a/addons/skin.estuary/xml/SettingsSystemInfo.xml
+++ b/addons/skin.estuary/xml/SettingsSystemInfo.xml
@@ -17,11 +17,11 @@
</control>
<control type="group">
<left>40</left>
- <top>70</top>
+ <top>133</top>
<include>OpenClose_Right</include>
<control type="grouplist">
<left>420</left>
- <top>105</top>
+ <top>30</top>
<height>550</height>
<orientation>vertical</orientation>
<control type="label" id="2">
@@ -83,14 +83,14 @@
<control type="textbox" id="30">
<left>420</left>
<right>50</right>
- <top>100</top>
+ <top>30</top>
<bottom>347</bottom>
<pagecontrol>60</pagecontrol>
<autoscroll delay="5000" repeat="7500" time="5000">!Control.HasFocus(60)</autoscroll>
</control>
<control type="scrollbar" id="60">
<right>0</right>
- <top>93</top>
+ <top>0</top>
<width>12</width>
<bottom>340</bottom>
<orientation>vertical</orientation>
@@ -106,7 +106,7 @@
</control>
<control type="image">
<left>380</left>
- <top>90</top>
+ <top>-3</top>
<right>0</right>
<height>3</height>
<texture colordiffuse="button_focus" border="2">dialogs/separator-grey.png</texture>
@@ -122,7 +122,7 @@
</include>
<control type="grouplist" id="9000">
<left>0</left>
- <top>160</top>
+ <top>130</top>
<width>420</width>
<height>100%</height>
<onup>9000</onup>
@@ -131,7 +131,7 @@
<control type="button" id="95">
<description>Button Summary Values</description>
<include content="DefaultSettingButton">
- <param name="height" value="88" />
+ <param name="height" value="85" />
</include>
<width>420</width>
<label>$LOCALIZE[20037]</label>
@@ -139,7 +139,7 @@
<control type="button" id="94">
<description>Button Storage</description>
<include content="DefaultSettingButton">
- <param name="height" value="88" />
+ <param name="height" value="85" />
</include>
<width>420</width>
<label>$LOCALIZE[13277]</label>
@@ -147,7 +147,7 @@
<control type="button" id="96">
<description>Button Network</description>
<include content="DefaultSettingButton">
- <param name="height" value="88" />
+ <param name="height" value="85" />
</include>
<width>420</width>
<label>$LOCALIZE[13279]</label>
@@ -155,7 +155,7 @@
<control type="button" id="97">
<description>Button Video</description>
<include content="DefaultSettingButton">
- <param name="height" value="88" />
+ <param name="height" value="85" />
</include>
<width>420</width>
<label>$LOCALIZE[13280]</label>
@@ -163,7 +163,7 @@
<control type="button" id="98">
<description>Button Hardware</description>
<include content="DefaultSettingButton">
- <param name="height" value="88" />
+ <param name="height" value="85" />
</include>
<width>420</width>
<label>$LOCALIZE[13281]</label>
@@ -171,7 +171,7 @@
<control type="button" id="99">
<description>Button PVR</description>
<include content="DefaultSettingButton">
- <param name="height" value="88" />
+ <param name="height" value="85" />
</include>
<width>420</width>
<label>$LOCALIZE[19191]</label>
@@ -179,7 +179,7 @@
<control type="button" id="100">
<description>Button Privacy policy</description>
<include content="DefaultSettingButton">
- <param name="height" value="88" />
+ <param name="height" value="85" />
</include>
<width>420</width>
<label>$LOCALIZE[12389]</label>
diff --git a/addons/skin.estuary/xml/SkinSettings.xml b/addons/skin.estuary/xml/SkinSettings.xml
index 34921db298..33ca748e9e 100644
--- a/addons/skin.estuary/xml/SkinSettings.xml
+++ b/addons/skin.estuary/xml/SkinSettings.xml
@@ -21,7 +21,7 @@
<left>470</left>
<include>OpenClose_Right</include>
<control type="grouplist" id="700">
- <top>160</top>
+ <top>133</top>
<left>0</left>
<right>0</right>
<bottom>140</bottom>
@@ -75,7 +75,7 @@
</control>
</control>
<control type="grouplist" id="600">
- <top>160</top>
+ <top>133</top>
<left>0</left>
<right>0</right>
<bottom>140</bottom>
@@ -131,7 +131,7 @@
</control>
</control>
<control type="grouplist" id="610">
- <top>160</top>
+ <top>133</top>
<left>0</left>
<right>0</right>
<bottom>140</bottom>
@@ -248,7 +248,7 @@
<control type="image">
<description>Dialog Header image</description>
<left>0</left>
- <top>160</top>
+ <top>130</top>
<right>0</right>
<height>3</height>
<texture colordiffuse="button_focus" border="2">dialogs/separator-grey.png</texture>
@@ -272,34 +272,34 @@
<control type="list" id="9000">
<description>button area</description>
<left>0</left>
- <top>160</top>
+ <top>130</top>
<width>470</width>
<height>700</height>
<onleft>10000</onleft>
<onright>10000</onright>
<onup>9000</onup>
<ondown>9000</ondown>
- <itemlayout height="90" width="470">
+ <itemlayout height="85" width="470">
<control type="label">
<textoffsetx>30</textoffsetx>
<width>470</width>
- <height>90</height>
+ <height>85</height>
<label>$INFO[ListItem.Label]</label>
<font>font37</font>
<aligny>center</aligny>
</control>
</itemlayout>
- <focusedlayout height="90" width="470">
+ <focusedlayout height="85" width="470">
<control type="image">
<width>470</width>
- <height>90</height>
+ <height>85</height>
<texture colordiffuse="button_focus">lists/focus.png</texture>
<animation effect="fade" start="100" end="50" time="40" condition="!Control.HasFocus(9000)">Conditional</animation>
</control>
<control type="label">
<textoffsetx>30</textoffsetx>
<width>470</width>
- <height>90</height>
+ <height>85</height>
<font>font37</font>
<aligny>center</aligny>
<label>$INFO[ListItem.Label]</label>
@@ -323,7 +323,7 @@
</control>
<control type="group">
<right>0</right>
- <top>163</top>
+ <top>133</top>
<bottom>137</bottom>
<width>60</width>
<control type="scrollbar" id="60">
diff --git a/addons/skin.estuary/xml/Variables.xml b/addons/skin.estuary/xml/Variables.xml
index 3ebe1121f0..3a4ff3b22f 100644
--- a/addons/skin.estuary/xml/Variables.xml
+++ b/addons/skin.estuary/xml/Variables.xml
@@ -136,6 +136,9 @@
<value condition="String.IsEmpty(listitem.Title)">$INFO[listitem.TrackNumber]</value>
<value>$INFO[listitem.TrackNumber,,.]$INFO[listitem.Title, ]</value>
</variable>
+ <variable name="MultiDiscVar">
+ <value condition="MusicPlayer.IsMultiDisc">$INFO[MusicPlayer.DiscNumber, - [$LOCALIZE[427] ,] ]$INFO[MusicPlayer.DiscTitle]</value>
+ </variable>
<variable name="WidgetGenreIconVar">
<value condition="System.AddonIsEnabled(resource.images.moviegenreicons.transparent)">$INFO[ListItem.Label,resource://resource.images.moviegenreicons.transparent/,.png]</value>
<value>DefaultGenre.png</value>
@@ -160,15 +163,29 @@
<value condition="Skin.HasSetting(show_profileavatar)">$LOCALIZE[31166]</value>
<value>$LOCALIZE[16018]</value>
</variable>
+ <variable name="AddonLifecycleType">
+ <value condition="String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24170])">[COLOR button_focus]$LOCALIZE[24170][/COLOR][CR]$INFO[ListItem.AddonLifecycleDesc]</value> <!-- Deprecated -->
+ <value condition="String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24171])">[COLOR button_focus]$LOCALIZE[24171][/COLOR][CR]$INFO[ListItem.AddonLifecycleDesc]</value> <!-- Broken -->
+ </variable>
<variable name="AddonsListIconVar">
- <value condition="!String.IsEmpty(ListItem.AddonBroken)">icons/addonstatus/disable.png</value>
+ <value condition="[String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24170]) | String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24171])] + !ListItem.Property(addon.isenabled)">icons/addonstatus/disable.png</value>
<value condition="ListItem.Property(addon.orphaned)">icons/addonstatus/orphan.png</value>
<value condition="ListItem.Property(addon.downloading)">icons/addonstatus/install.png</value>
<value condition="ListItem.Property(addon.isinstalled) + !ListItem.Property(addon.isenabled) + Window.IsActive(addonbrowser)">icons/addonstatus/disable.png</value>
<value condition="ListItem.Property(addon.hasupdate)">icons/addonstatus/update.png</value>
- <value condition="ListItem.Property(addon.isinstalled)">OverlayWatched.png</value>
+ <value condition="ListItem.Property(addon.isenabled) + String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24169])">icons/addonstatus/enabled-normal.png</value>
+ <value condition="ListItem.Property(addon.isenabled) + String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24170])">icons/addonstatus/enabled-deprecated.png</value>
+ <value condition="ListItem.Property(addon.isenabled) + String.IsEqual(ListItem.AddonLifecycleType,$LOCALIZE[24171])">icons/addonstatus/enabled-broken.png</value>
<value condition="!ListItem.IsParentFolder">OverlayUnwatched.png</value>
</variable>
+ <variable name="AddonsOriginVar">
+ <value condition="ListItem.Property(Addon.IsFromOfficialRepo) + ListItem.IsAutoUpdateable">icons/addonstatus/official.png</value>
+ <value condition="ListItem.Property(Addon.IsFromOfficialRepo)">icons/addonstatus/official-pinned.png</value>
+ <value condition="String.IsEqual(ListItem.AddonOrigin,$LOCALIZE[25014]) + ListItem.IsAutoUpdateable">icons/addonstatus/manual.png</value>
+ <value condition="String.IsEqual(ListItem.AddonOrigin,$LOCALIZE[25014])">icons/addonstatus/manual-pinned.png</value>
+ <value condition="ListItem.IsAutoUpdateable">icons/addonstatus/install.png</value>
+ <value>icons/addonstatus/install-pinned.png</value>
+ </variable>
<variable name="ResolutionFlagVar">
<value condition="ListItem.IsStereoscopic">flags/videoresolution/3D.png</value>
<value>$INFO[ListItem.VideoResolution,flags/videoresolution/,.png]</value>
diff --git a/addons/skin.estuary/xml/View_55_WideList.xml b/addons/skin.estuary/xml/View_55_WideList.xml
index d67bac5611..391fdcaca8 100644
--- a/addons/skin.estuary/xml/View_55_WideList.xml
+++ b/addons/skin.estuary/xml/View_55_WideList.xml
@@ -275,12 +275,20 @@
<control type="label">
<left>75</left>
<height>80</height>
- <right>40</right>
+ <right>90</right>
<align>right</align>
<aligny>center</aligny>
<font>font27</font>
<label>$VAR[AddonsLabel2Var]</label>
</control>
+ <control type="image">
+ <right>40</right>
+ <top>25</top>
+ <width>32</width>
+ <height>32</height>
+ <texture>$VAR[AddonsOriginVar]</texture>
+ <visible>!ListItem.IsFolder</visible>
+ </control>
</focusedlayout>
<itemlayout height="80" condition="Container.Content(addons)">
<control type="image">
@@ -301,7 +309,7 @@
<control type="label">
<left>75</left>
<height>80</height>
- <right>40</right>
+ <right>90</right>
<align>right</align>
<aligny>center</aligny>
<font>font27</font>
@@ -309,6 +317,14 @@
<textcolor>grey</textcolor>
<shadowcolor>text_shadow</shadowcolor>
</control>
+ <control type="image">
+ <right>40</right>
+ <top>25</top>
+ <width>32</width>
+ <height>32</height>
+ <texture>$VAR[AddonsOriginVar]</texture>
+ <visible>!ListItem.IsFolder</visible>
+ </control>
</itemlayout>
</include>
</includes>
diff --git a/addons/xbmc.addon/metadata.xsd b/addons/xbmc.addon/metadata.xsd
index e1e35d9468..86a867e919 100644
--- a/addons/xbmc.addon/metadata.xsd
+++ b/addons/xbmc.addon/metadata.xsd
@@ -14,7 +14,7 @@
<xs:element name="website" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="source" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="email" type="xs:string" minOccurs="0" maxOccurs="1"/>
- <xs:element name="broken" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="lifecyclestate" type="translatedLifecycleState" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="news" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="reuselanguageinvoker" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="assets" type="assetsList" minOccurs="0" maxOccurs="1"/>
@@ -36,6 +36,14 @@
</xs:extension>
</xs:simpleContent>
</xs:complexType>
+ <xs:complexType name="translatedLifecycleState">
+ <xs:simpleContent>
+ <xs:extension base="nonEmptyStringCapped">
+ <xs:attribute name="type" type="lifecycleStateType" use="required"/>
+ <xs:attribute name="lang" type="langIdentifier"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
<xs:simpleType name="platformType">
<xs:restriction base="xs:string">
<xs:enumeration value="linux"/>
@@ -55,6 +63,13 @@
<xs:pattern value="[a-z]{2,3}(_[A-Z]{2}(@\S+)?)?"/>
</xs:restriction>
</xs:simpleType>
+ <xs:simpleType name="lifecycleStateType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="normal"/>
+ <xs:enumeration value="deprecated"/>
+ <xs:enumeration value="broken"/>
+ </xs:restriction>
+ </xs:simpleType>
<xs:complexType name="assetsList">
<xs:choice maxOccurs="unbounded">
<xs:element name="icon" type="xs:string" minOccurs="0" maxOccurs="1"/>
diff --git a/cmake/addons/CMakeLists.txt b/cmake/addons/CMakeLists.txt
index 3dccc014b2..c1313d7458 100644
--- a/cmake/addons/CMakeLists.txt
+++ b/cmake/addons/CMakeLists.txt
@@ -244,26 +244,80 @@ endif()
# error either in ADDONS_TO_BUILD or in the directory configuration.
set(SUPPORTED_ADDON_FOUND FALSE)
+if(NOT ADDONS_TO_BUILD)
+ set(ADDONS_TO_BUILD "all")
+endif()
+
+if(NOT ADDONS_TO_BUILD STREQUAL "all")
+ # Exact addon match list
+ set(REGEX_ADDONS_TO_BUILD ${ADDONS_TO_BUILD})
+ set(EXACT_MATCH_ADDON_LIST "")
+ set(EXCLUDE_ADDONS "")
+
+ foreach(addon ${ADDONS_TO_BUILD})
+ set(FOUND_EXCLUSION "")
+ string(REGEX MATCH "^[-](.*)" FOUND_EXCLUSION "${addon}")
+ if(NOT FOUND_EXCLUSION STREQUAL "")
+ list(APPEND EXCLUDE_ADDONS ${CMAKE_MATCH_1})
+ list(REMOVE_ITEM REGEX_ADDONS_TO_BUILD "-${CMAKE_MATCH_1}")
+ else()
+ foreach(addonrepoitem ${addons})
+ if(NOT (addonrepoitem MATCHES platforms.txt))
+ # need to strip regex chars, or the filter regex will use
+ string(REPLACE "*" "" strippedregex ${addon})
+ if(${addonrepoitem} MATCHES "^.*\/(${strippedregex}).txt")
+ list(APPEND EXACT_MATCH_ADDON_LIST ${addon})
+ # remove exact matches from addons_to_build
+ list(REMOVE_ITEM REGEX_ADDONS_TO_BUILD "${addon}")
+ endif()
+ endif()
+ endforeach()
+ endif()
+ endforeach()
+
+ message(STATUS "Exclusion list: ${EXCLUDE_ADDONS}")
+ message(STATUS "Exact Match list: ${EXACT_MATCH_ADDON_LIST}")
+ message(STATUS "Regex list: ${REGEX_ADDONS_TO_BUILD}")
+endif()
+
foreach(addon ${addons})
if(NOT (addon MATCHES platforms.txt))
file(STRINGS ${addon} def)
string(REPLACE " " ";" def ${def})
list(GET def 0 id)
- set(ADDON_FOUND FALSE)
- # try to find a perfect match
- list(FIND ADDONS_TO_BUILD ${id} idx)
- if(idx GREATER -1 OR "${ADDONS_TO_BUILD}" STREQUAL "all")
+ if("${ADDONS_TO_BUILD}" STREQUAL "all")
set(ADDON_FOUND TRUE)
- # Maybe we have a regex
else()
- foreach(ADDONLISTITEM ${ADDONS_TO_BUILD})
- if(id MATCHES "${ADDONLISTITEM}")
- message(STATUS "Pattern ${ADDONLISTITEM} matches ${id}, building addon")
- set(ADDON_FOUND TRUE)
+ set(ADDON_EXCLUDE FALSE)
+ set(ADDON_FOUND FALSE)
+ foreach(exclusion ${EXCLUDE_ADDONS})
+ if(id MATCHES "${exclusion}")
+ set(ADDON_EXCLUDE TRUE)
+ message(STATUS "Addon ${id} matches exclusion rule -${exclusion}")
break()
endif()
endforeach()
+
+ if(ADDON_EXCLUDE)
+ continue()
+ endif()
+
+ list(FIND EXACT_MATCH_ADDON_LIST ${id} idx)
+ if(idx GREATER -1)
+ # exact match, so build
+ message(STATUS "Exact match ${id}, building addon")
+ set(ADDON_FOUND TRUE)
+ else()
+ # regex search
+ foreach(ADDONLISTITEM ${REGEX_ADDONS_TO_BUILD})
+ if(id MATCHES "${ADDONLISTITEM}")
+ message(STATUS "Pattern ${ADDONLISTITEM} matches ${id}, building addon")
+ set(ADDON_FOUND TRUE)
+ break()
+ endif()
+ endforeach()
+ endif()
endif()
if(ADDON_FOUND)
diff --git a/cmake/addons/README.md b/cmake/addons/README.md
index 17e6460d75..ed1894e00a 100644
--- a/cmake/addons/README.md
+++ b/cmake/addons/README.md
@@ -18,16 +18,18 @@ where
List of platforms to build an add-on for (or *all*). Negating platforms is supported using a leading exclamation mark, e.g. *!windows*.
-Available platforms are: linux, windows, osx, ios, android, rbpi and freebsd.
+Available platforms are: linux, windows, osx, ios, android and freebsd.
#### Attention
If no add-on definitions could be found, the buildsystem assumes that the bootstrapping of the add-on definition repositories hasn't been performed yet and automatically executes the add-on bootstrapping buildsystem located in the *bootstrap* sub-directory with the default settings (i.e. *all* add-ons from all pre-defined add-on definition repositories are bootstrapped into the directory pointed to by the *ADDONS_DEFINITION_DIR* option).
## Buildsystem variables
The buildsystem uses the following addon-related variables (which can be passed into it when executing cmake with the -D`<variable-name>=<value>` format) to manipulate the build process:
-- `ADDONS_TO_BUILD` has two variations, which are tested in order:
- - a quoted, space delimited list of `<addon-id>s` that you want to build (default is *all*)
- - a regular expression that every `<addon-id>` is matched against (e.g. `ADDONS_TO_BUILD="pvr.*"`) to build all pvr add-ons
+- `ADDONS_TO_BUILD` has four rules for matching a provided space delimited list:
+ - to build all addons, just use `all` (default is *all*)
+ - an exact match of an `<addon-id>` that you want to build (e.g. `ADDONS_TO_BUILD="game.libretro"`)
+ - a regular expression `<addon-id>` is matched against (e.g. `ADDONS_TO_BUILD="pvr.*"`) to build all pvr add-ons
+ - a regular expression exclusion can be made using `-<addon-id regex>` (e.g. `ADDONS_TO_BUILD="pvr.* -pvr.dvb"`) to exclude pvr.dvblink and pvr.dvbviewer, but build all other pvr add-ons
- `ADDONS_DEFINITION_DIR` points to the directory containing the definitions for the addons to be built
- `ADDON_SRC_PREFIX` can be used to override the add-on repository location. It must point to the locally available parent directory of the add-on(s) to build. `<addon-id>` will be appended to this path automatically
- `CMAKE_INSTALL_PREFIX` points to the directory where the built add-ons and their additional files (addon.xml, resources, ...) will be installed to (defaults to `<ADDON_DEPENDS_PATH>`)
@@ -44,4 +46,4 @@ Buildsystem will print a warning if you use any of the below-listed variables. F
## Building
The buildsystem makes some assumptions about the environment which must be met by whoever uses it:
-- Any dependencies of the add-ons must already be built and their include and library files must be present in the path pointed to by `<CMAKE_PREFIX_PATH>` (in *include* and *lib* sub-directories) \ No newline at end of file
+- Any dependencies of the add-ons must already be built and their include and library files must be present in the path pointed to by `<CMAKE_PREFIX_PATH>` (in *include* and *lib* sub-directories)
diff --git a/cmake/cpack/deb/packages/kodi.txt.in b/cmake/cpack/deb/packages/kodi.txt.in
index 78df46ae47..6cce5fd6b2 100644
--- a/cmake/cpack/deb/packages/kodi.txt.in
+++ b/cmake/cpack/deb/packages/kodi.txt.in
@@ -15,7 +15,7 @@ PACKAGE_ARCHITECTURE all
PACKAGE_SECTION video
PACKAGE_PRIORITY optional
PACKAGE_SHLIBDEPS
-PACKAGE_DEPENDS @APP_NAME_LC@-bin (>= @CPACK_DEBIAN_PACKAGE_VERSION@), @APP_NAME_LC@-bin (<< @CPACK_DEBIAN_PACKAGE_VERSION@.1~), curl, libcurl4 | libcurl3, mesa-utils, x11-utils, fonts-liberation | ttf-liberation, fonts-dejavu-core | ttf-dejavu-core, python3-pil, python3-simplejson, libass9 | libass5 | libass4, libgif5 | libgif7, libnfs8 | libnfs4 | libnfs1, libbluray1 | libbluray2, libshairplay0, libvorbisfile3, libaacs0, libcec4, libgnutls30 | libgnutls-deb0-28 | libgnutls28 | libgnutls26, libxslt1.1
+PACKAGE_DEPENDS @APP_NAME_LC@-bin (>= @CPACK_DEBIAN_PACKAGE_VERSION@), @APP_NAME_LC@-bin (<< @CPACK_DEBIAN_PACKAGE_VERSION@.1~), curl, libcurl4 | libcurl3, mesa-utils, x11-utils, fonts-liberation | ttf-liberation, fonts-dejavu-core | ttf-dejavu-core, python3-pil, python3-simplejson, libass9 | libass5 | libass4, libgif5 | libgif7, libnfs8 | libnfs4 | libnfs1, libbluray1 | libbluray2, libshairplay0, libvorbisfile3, libaacs0, libcec6 | libcec4, libgnutls30 | libgnutls-deb0-28 | libgnutls28 | libgnutls26, libxslt1.1
PACKAGE_RECOMMENDS libvdpau1, libva-intel-vaapi-driver, libva1
PACKAGE_SUGGESTS @APP_NAME_LC@-pvr-mythtv, @APP_NAME_LC@-pvr-vuplus, @APP_NAME_LC@-pvr-vdr-vnsi, @APP_NAME_LC@-pvr-njoy, @APP_NAME_LC@-pvr-nextpvr, @APP_NAME_LC@-pvr-mediaportal-tvserver, @APP_NAME_LC@-pvr-tvheadend-hts, @APP_NAME_LC@-pvr-dvbviewer, @APP_NAME_LC@-pvr-argustv, @APP_NAME_LC@-pvr-iptvsimple, @APP_NAME_LC@-audioencoder-vorbis, @APP_NAME_LC@-audioencoder-flac, @APP_NAME_LC@-audioencoder-lame
PACKAGE_BREAKS xbmc (<< 2:14.0~git20141019), xbmc-data, xbmc-standalone
diff --git a/cmake/installdata/rbpi/lirc.txt b/cmake/installdata/rbpi/lirc.txt
deleted file mode 120000
index e89ae50094..0000000000
--- a/cmake/installdata/rbpi/lirc.txt
+++ /dev/null
@@ -1 +0,0 @@
-../linux/lirc.txt \ No newline at end of file
diff --git a/cmake/modules/FindEGL.cmake b/cmake/modules/FindEGL.cmake
index 0b73eb80bc..b00fe08a25 100644
--- a/cmake/modules/FindEGL.cmake
+++ b/cmake/modules/FindEGL.cmake
@@ -14,18 +14,14 @@
#
# EGL::EGL - The EGL library
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- set(_brcmprefix brcm)
-endif()
-
if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_EGL ${_brcmprefix}egl QUIET)
+ pkg_check_modules(PC_EGL egl QUIET)
endif()
find_path(EGL_INCLUDE_DIR EGL/egl.h
PATHS ${PC_EGL_INCLUDEDIR})
-find_library(EGL_LIBRARY NAMES ${_brcmprefix}EGL egl
+find_library(EGL_LIBRARY NAMES EGL egl
PATHS ${PC_EGL_LIBDIR})
set(EGL_VERSION ${PC_EGL_VERSION})
diff --git a/cmake/modules/FindLCMS2.cmake b/cmake/modules/FindLCMS2.cmake
index 7cc1497333..d02515815d 100644
--- a/cmake/modules/FindLCMS2.cmake
+++ b/cmake/modules/FindLCMS2.cmake
@@ -15,7 +15,7 @@
# LCMS2::LCMS2 - The LCMS Color Management library
if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_LCMS2 lcms2 QUIET)
+ pkg_check_modules(PC_LCMS2 lcms2>=2.10 QUIET)
endif()
find_path(LCMS2_INCLUDE_DIR NAMES lcms2.h
@@ -33,7 +33,7 @@ find_package_handle_standard_args(LCMS2
if(LCMS2_FOUND)
set(LCMS2_LIBRARIES ${LCMS2_LIBRARY})
set(LCMS2_INCLUDE_DIRS ${LCMS2_INCLUDE_DIR})
- set(LCMS2_DEFINITIONS -DHAVE_LCMS2=1)
+ set(LCMS2_DEFINITIONS -DHAVE_LCMS2=1 -DCMS_NO_REGISTER_KEYWORD=1)
if(NOT TARGET LCMS2::LCMS2)
add_library(LCMS2::LCMS2 UNKNOWN IMPORTED)
diff --git a/cmake/modules/FindLibDRM.cmake b/cmake/modules/FindLibDRM.cmake
index 0d680f2b99..866565dbd3 100644
--- a/cmake/modules/FindLibDRM.cmake
+++ b/cmake/modules/FindLibDRM.cmake
@@ -15,7 +15,7 @@
# LibDRM::LibDRM - The LibDRM library
if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_LIBDRM libdrm>=2.4.82 QUIET)
+ pkg_check_modules(PC_LIBDRM libdrm>=2.4.95 QUIET)
endif()
find_path(LIBDRM_INCLUDE_DIR NAMES drm.h
diff --git a/cmake/modules/FindLibDvd.cmake b/cmake/modules/FindLibDvd.cmake
index 44e7e92cb2..58a7aab309 100644
--- a/cmake/modules/FindLibDvd.cmake
+++ b/cmake/modules/FindLibDvd.cmake
@@ -96,6 +96,16 @@ else()
set(LIBDVD_ADDITIONAL_ARGS "-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}" "-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}")
endif()
+ set(MAKE_COMMAND $(MAKE))
+ if(CMAKE_GENERATOR STREQUAL Ninja)
+ set(MAKE_COMMAND make)
+ include(ProcessorCount)
+ ProcessorCount(N)
+ if(NOT N EQUAL 0)
+ set(MAKE_COMMAND make -j${N})
+ endif()
+ endif()
+
if(ENABLE_DVDCSS)
if(NOT CORE_SYSTEM_NAME MATCHES windows)
set(DVDCSS_LIBRARY ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib/libdvdcss.a)
@@ -115,6 +125,7 @@ else()
"CC=${CMAKE_C_COMPILER}"
"CFLAGS=${CMAKE_C_FLAGS} ${DVDREAD_CFLAGS}"
"LDFLAGS=${CMAKE_LD_FLAGS}"
+ BUILD_COMMAND ${MAKE_COMMAND}
BUILD_BYPRODUCTS ${DVDCSS_LIBRARY})
ExternalProject_Add_Step(dvdcss autoreconf
DEPENDEES download update patch
@@ -156,7 +167,8 @@ else()
"CC=${CMAKE_C_COMPILER}"
"CFLAGS=${CMAKE_C_FLAGS} ${DVDREAD_CFLAGS}"
"LDFLAGS=${CMAKE_LD_FLAGS}"
- BUILD_BYPRODUCTS ${DVDREAD_LIBRARY})
+ BUILD_COMMAND ${MAKE_COMMAND}
+ BUILD_BYPRODUCTS ${DVDREAD_LIBRARY})
ExternalProject_Add_Step(dvdread autoreconf
DEPENDEES download update patch
DEPENDERS configure
@@ -203,6 +215,7 @@ else()
"DVDREAD_CFLAGS=${DVDREAD_CFLAGS}"
"DVDREAD_LIBS=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib/libdvdread.la"
"LIBS=${DVDNAV_LIBS}"
+ BUILD_COMMAND ${MAKE_COMMAND}
BUILD_BYPRODUCTS ${DVDNAV_LIBRARY})
ExternalProject_Add_Step(dvdnav autoreconf
DEPENDEES download update patch
diff --git a/cmake/modules/FindMMAL.cmake b/cmake/modules/FindMMAL.cmake
deleted file mode 100644
index 0b5f5564ec..0000000000
--- a/cmake/modules/FindMMAL.cmake
+++ /dev/null
@@ -1,55 +0,0 @@
-# - Try to find MMAL
-# Once done this will define
-#
-# MMAL_FOUND - system has MMAL
-# MMAL_INCLUDE_DIRS - the MMAL include directory
-# MMAL_LIBRARIES - The MMAL libraries
-
-if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_MMAL mmal QUIET)
-endif()
-
-
-find_path(MMAL_INCLUDE_DIR NAMES interface/mmal/mmal.h PATHS ${PC_MMAL_INCLUDEDIR})
-find_library(MMAL_LIBRARY NAMES mmal libmmal PATHS ${PC_MMAL_LIBDIR})
-find_library(MMALCORE_LIBRARY NAMES mmal_core libmmal_core PATHS ${PC_MMAL_LIBDIR})
-find_library(MMALUTIL_LIBRARY NAMES mmal_util libmmal_util PATHS ${PC_MMAL_LIBDIR})
-find_library(MMALCLIENT_LIBRARY NAMES mmal_vc_client libmmal_vc_client PATHS ${PC_MMAL_LIBDIR})
-find_library(MMALCOMPONENT_LIBRARY NAMES mmal_components libmmal_components PATHS ${PC_MMAL_LIBDIR})
-find_library(BCM_LIBRARY NAMES bcm_host libbcm_host PATHS ${PC_MMAL_LIBDIR})
-find_library(VCHIQ_LIBRARY NAMES vchiq_arm libvchiq_arm PATHS ${PC_MMAL_LIBDIR})
-find_library(VCHOSTIF_LIBRARY NAMES vchostif libvchostif PATHS ${PC_MMAL_LIBDIR})
-find_library(VCILCS_LIBRARY NAMES vcilcs libvcilcs PATHS ${PC_MMAL_LIBDIR})
-find_library(VCOS_LIBRARY NAMES vcos libvcos PATHS ${PC_MMAL_LIBDIR})
-find_library(VCSM_LIBRARY NAMES vcsm libvcsm PATHS ${PC_MMAL_LIBDIR})
-find_library(CONTAINER_LIBRARY NAMES containers libcontainers PATHS ${PC_MMAL_LIBDIR})
-
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(MMAL REQUIRED_VARS MMAL_INCLUDE_DIR
- MMAL_LIBRARY MMALCORE_LIBRARY MMALUTIL_LIBRARY
- MMALCLIENT_LIBRARY MMALCOMPONENT_LIBRARY BCM_LIBRARY
- VCHIQ_LIBRARY VCOS_LIBRARY VCSM_LIBRARY VCHOSTIF_LIBRARY
- VCILCS_LIBRARY CONTAINER_LIBRARY)
-
-
-if(MMAL_FOUND)
- set(MMAL_INCLUDE_DIRS ${MMAL_INCLUDE_DIR})
- set(MMAL_LIBRARIES ${MMAL_LIBRARY} ${MMALCORE_LIBRARY} ${MMALUTIL_LIBRARY}
- ${MMALCLIENT_LIBRARY} ${MMALCOMPONENT_LIBRARY}
- ${BCM_LIBRARY} ${VCHIQ_LIBRARY} ${VCOS_LIBRARY} ${VCSM_LIBRARY}
- ${VCHOSTIF_LIBRARY} ${VCILCS_LIBRARY} ${CONTAINER_LIBRARY}
- CACHE STRING "mmal libraries" FORCE)
- list(APPEND MMAL_DEFINITIONS -DHAVE_MMAL=1 -DHAS_MMAL=1)
-
- if(NOT TARGET MMAL::MMAL)
- add_library(MMAL::MMAL UNKNOWN IMPORTED)
- set_target_properties(MMAL::MMAL PROPERTIES
- IMPORTED_LOCATION "${MMAL_LIBRARIES}"
- INTERFACE_INCLUDE_DIRECTORIES "${MMAL_INCLUDE_DIR}")
- endif()
-endif()
-
-mark_as_advanced(MMAL_INCLUDE_DIRS MMAL_LIBRARIES MMAL_DEFINITIONS
- MMAL_LIBRARY MMALCORE_LIBRARY MMALUTIL_LIBRARY MMALCLIENT_LIBRARY MMALCOMPONENT_LIBRARY BCM_LIBRARY
- VCHIQ_LIBRARY VCOS_LIBRARY VCSM_LIBRARY VCHOSTIF_LIBRARY VCILCS_LIBRARY CONTAINER_LIBRARY)
diff --git a/cmake/modules/FindOpenGLES.cmake b/cmake/modules/FindOpenGLES.cmake
index 43a1367a52..3dbaa447fa 100644
--- a/cmake/modules/FindOpenGLES.cmake
+++ b/cmake/modules/FindOpenGLES.cmake
@@ -10,18 +10,14 @@
# OPENGLES_LIBRARIES - the OpenGLES libraries
# OPENGLES_DEFINITIONS - the OpenGLES definitions
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- set(_brcmprefix brcm)
-endif()
-
if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_OPENGLES ${_brcmprefix}glesv2 QUIET)
+ pkg_check_modules(PC_OPENGLES glesv2 QUIET)
endif()
if(NOT CORE_SYSTEM_NAME STREQUAL darwin_embedded)
find_path(OPENGLES_INCLUDE_DIR GLES2/gl2.h
PATHS ${PC_OPENGLES_INCLUDEDIR})
- find_library(OPENGLES_gl_LIBRARY NAMES ${_brcmprefix}GLESv2
+ find_library(OPENGLES_gl_LIBRARY NAMES GLESv2
PATHS ${PC_OPENGLES_LIBDIR})
else()
find_library(OPENGLES_gl_LIBRARY NAMES OpenGLES
diff --git a/cmake/modules/FindPlist.cmake b/cmake/modules/FindPlist.cmake
index 2c86b7493a..8f9b2d6cd7 100644
--- a/cmake/modules/FindPlist.cmake
+++ b/cmake/modules/FindPlist.cmake
@@ -15,7 +15,7 @@
# Plist::Plist - The Plist library
if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_PLIST libplist QUIET)
+ pkg_search_module(PC_PLIST libplist-2.0 libplist QUIET)
endif()
find_path(PLIST_INCLUDE_DIR plist/plist.h
@@ -23,7 +23,7 @@ find_path(PLIST_INCLUDE_DIR plist/plist.h
set(PLIST_VERSION ${PC_PLIST_VERSION})
-find_library(PLIST_LIBRARY NAMES plist libplist
+find_library(PLIST_LIBRARY NAMES plist-2.0 plist libplist-2.0 libplist
PATHS ${PC_PLIST_LIBDIR})
include(FindPackageHandleStandardArgs)
diff --git a/cmake/platform/freebsd/rbpi.cmake b/cmake/platform/freebsd/rbpi.cmake
deleted file mode 100644
index f0956939b6..0000000000
--- a/cmake/platform/freebsd/rbpi.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include(cmake/platform/linux/rbpi.cmake)
diff --git a/cmake/platform/linux/rbpi.cmake b/cmake/platform/linux/rbpi.cmake
deleted file mode 100644
index 3dde57dce5..0000000000
--- a/cmake/platform/linux/rbpi.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(PLATFORM_REQUIRED_DEPS OpenGLES EGL MMAL LibInput Xkbcommon)
-set(APP_RENDER_SYSTEM gles)
-list(APPEND PLATFORM_DEFINES -D_ARMEL -DTARGET_RASPBERRY_PI)
diff --git a/cmake/scripts/common/CompilerSettings.cmake b/cmake/scripts/common/CompilerSettings.cmake
index b4e7e89220..bb0af925ce 100644
--- a/cmake/scripts/common/CompilerSettings.cmake
+++ b/cmake/scripts/common/CompilerSettings.cmake
@@ -1,7 +1,5 @@
# Languages and global compiler settings
-if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 14)
- set(CMAKE_CXX_STANDARD 14)
-endif()
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp")
diff --git a/cmake/scripts/darwin_embedded/ExtraTargets.cmake b/cmake/scripts/darwin_embedded/ExtraTargets.cmake
index 1b984f36b8..01ab6328c5 100644
--- a/cmake/scripts/darwin_embedded/ExtraTargets.cmake
+++ b/cmake/scripts/darwin_embedded/ExtraTargets.cmake
@@ -23,5 +23,10 @@ if(CORE_PLATFORM_NAME_LC STREQUAL tvos)
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${ENTITLEMENTS_OUT_PATH})
target_link_libraries(${TOPSHELF_EXTENSION_NAME} "-framework TVServices" "-framework Foundation")
+ add_custom_command(TARGET ${TOPSHELF_EXTENSION_NAME} POST_BUILD
+ COMMAND "NATIVEPREFIX=${NATIVEPREFIX}"
+ ${CMAKE_SOURCE_DIR}/tools/darwin/Support/Codesign-topshelf.command
+ )
+
add_dependencies(${APP_NAME_LC} ${TOPSHELF_EXTENSION_NAME})
endif()
diff --git a/cmake/scripts/linux/ArchSetup.cmake b/cmake/scripts/linux/ArchSetup.cmake
index 04fc6e3ffd..b68efe3bd0 100644
--- a/cmake/scripts/linux/ArchSetup.cmake
+++ b/cmake/scripts/linux/ArchSetup.cmake
@@ -37,16 +37,6 @@ else()
endif()
endif()
-# temp until further cleanup is done
-# add Raspberry Pi 2 and 3 specific flags
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- if(CPU MATCHES "cortex-a7")
- set(NEON_FLAGS "-fPIC -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -mvectorize-with-neon-quad")
- elseif(CPU MATCHES "cortex-a53")
- set(NEON_FLAGS "-fPIC -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mvectorize-with-neon-quad")
- endif()
-endif()
-
if((CMAKE_BUILD_TYPE STREQUAL Release OR CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
AND CMAKE_COMPILER_IS_GNUCXX)
# Make sure we strip binaries in Release build
diff --git a/cmake/scripts/windowsstore/ArchSetup.cmake b/cmake/scripts/windowsstore/ArchSetup.cmake
index ad55a01ac8..9473a4bb61 100644
--- a/cmake/scripts/windowsstore/ArchSetup.cmake
+++ b/cmake/scripts/windowsstore/ArchSetup.cmake
@@ -79,7 +79,6 @@ list(APPEND SYSTEM_DEFINES -DHAS_WIN10_NETWORK)
# The /MP option enables /FS by default.
set(CMAKE_CXX_FLAGS "/MP ${CMAKE_CXX_FLAGS} /EHsc /await")
-set(CMAKE_CXX_STANDARD 17)
# Google Test needs to use shared version of runtime libraries
set(gtest_force_shared_crt ON CACHE STRING "" FORCE)
diff --git a/cmake/treedata/common/rbpi/rbpi.txt b/cmake/treedata/common/rbpi/rbpi.txt
deleted file mode 100644
index dc268e773c..0000000000
--- a/cmake/treedata/common/rbpi/rbpi.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-xbmc/cores/omxplayer cores/omxplayer
-xbmc/windowing/rpi windowing/rpi
diff --git a/cmake/treedata/common/subdirs.txt b/cmake/treedata/common/subdirs.txt
index 37b720996d..64f1c9fc50 100644
--- a/cmake/treedata/common/subdirs.txt
+++ b/cmake/treedata/common/subdirs.txt
@@ -7,16 +7,22 @@ xbmc/addons/interfaces addons_interfaces
xbmc/addons/interfaces/gui addons_interfaces_gui
xbmc/addons/interfaces/gui/controls addons_interfaces_gui_controls
xbmc/addons/interfaces/gui/dialogs addons_interfaces_gui_dialogs
-xbmc/addons/kodi-dev-kit/include/kodi addons_kodi-dev-kit_include_kodi
+xbmc/addons/kodi-dev-kit/include/kodi addons_kodi-dev-kit_include_kodi
xbmc/addons/kodi-dev-kit/include/kodi/addon-instance addons_kodi-dev-kit_include_kodi_addon-instance
+xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral addons_kodi-dev-kit_include_kodi_addon-instance_peripheral
xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/pvr addons_kodi-dev-kit_include_kodi_addon-instance_pvr
xbmc/addons/kodi-dev-kit/include/kodi/c-api addons_kodi-dev-kit_include_kodi_c-api
xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance addons_kodi-dev-kit_include_kodi_c-api_addon-instance
xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr addons_kodi-dev-kit_include_kodi_c-api_addon-instance_pvr
+xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui addons_kodi-dev-kit_include_kodi_c-api_gui
+xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls addons_kodi-dev-kit_include_kodi_c-api_gui_controls
+xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs addons_kodi-dev-kit_include_kodi_c-api_gui_dialogs
+xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input addons_kodi-dev-kit_include_kodi_c-api_gui_input
xbmc/addons/kodi-dev-kit/include/kodi/gui addons_kodi-dev-kit_include_kodi_gui
xbmc/addons/kodi-dev-kit/include/kodi/gui/controls addons_kodi-dev-kit_include_kodi_gui_controls
xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs addons_kodi-dev-kit_include_kodi_gui_dialogs
xbmc/addons/kodi-dev-kit/include/kodi/gui/gl addons_kodi-dev-kit_include_kodi_gui_gl
+xbmc/addons/kodi-dev-kit/include/kodi/gui/input addons_kodi-dev-kit_include_kodi_gui_input
xbmc/addons/kodi-dev-kit/include/kodi/tools addons_kodi-dev-kit_include_kodi_tools
xbmc/addons/settings addons_settings
xbmc/commons commons
diff --git a/cmake/treedata/freebsd/subdirs.txt b/cmake/treedata/freebsd/subdirs.txt
index 79e3462cf4..a7433a5a62 100644
--- a/cmake/treedata/freebsd/subdirs.txt
+++ b/cmake/treedata/freebsd/subdirs.txt
@@ -1,5 +1,3 @@
-xbmc/cores/RetroPlayer/process/rbpi cores/RetroPlayer/process/rbpi
-xbmc/cores/VideoPlayer/Process/rbpi cores/VideoPlayer/Process/rbpi
xbmc/input/touch input/touch
xbmc/input/touch/generic input/touch/generic
xbmc/platform/freebsd platform/freebsd
diff --git a/cmake/treedata/linux/subdirs.txt b/cmake/treedata/linux/subdirs.txt
index 51a7cbd73a..35c8d88c15 100644
--- a/cmake/treedata/linux/subdirs.txt
+++ b/cmake/treedata/linux/subdirs.txt
@@ -1,5 +1,3 @@
-xbmc/cores/RetroPlayer/process/rbpi cores/RetroPlayer/process/rbpi
-xbmc/cores/VideoPlayer/Process/rbpi cores/VideoPlayer/Process/rbpi
xbmc/input/touch input/touch
xbmc/input/touch/generic input/touch/generic
xbmc/platform/linux platform/linux
diff --git a/docs/README.Android.md b/docs/README.Android.md
index 5d918d6887..1f8cb47073 100644
--- a/docs/README.Android.md
+++ b/docs/README.Android.md
@@ -192,6 +192,7 @@ Build a specific group of add-ons:
```
make -j$(getconf _NPROCESSORS_ONLN) -C tools/depends/target/binary-addons ADDONS="pvr.*"
```
+For additional information on regular expression usage for ADDONS_TO_BUILD, view ADDONS_TO_BUILD section located at [Kodi add-ons CMake based buildsystem](../cmake/addons/README.md)
**[back to top](#table-of-contents)**
diff --git a/docs/README.Fedora.md b/docs/README.Fedora.md
index b38c49babd..a978259597 100644
--- a/docs/README.Fedora.md
+++ b/docs/README.Fedora.md
@@ -61,7 +61,7 @@ git clone https://github.com/xbmc/xbmc kodi
## 3. Install the required packages
If you get a `package not found` type of message with the below command, remove the offending package(s) from the install list and reissue the command. Take a note of the missing dependencies and, after a successful step completion, **[build the missing dependencies manually](README.Linux.md#31-build-missing-dependencies)**.
-**NOTE:** Kodi requires a compiler with C++14 support, i.e. gcc >= 4.9 or clang >= 3.4
+**NOTE:** Kodi requires a compiler with C++17 support, i.e. gcc >= 7 or clang >= 5
Install build dependencies:
```
diff --git a/docs/README.FreeBSD.md b/docs/README.FreeBSD.md
index 75e5985171..8424cc1aa6 100644
--- a/docs/README.FreeBSD.md
+++ b/docs/README.FreeBSD.md
@@ -72,7 +72,7 @@ git clone https://github.com/xbmc/xbmc kodi
## 3. Install the required packages
If you get a `package not found` type of message with the below command, remove the offending package(s) from the install list and reissue the command. Take a note of the missing dependencies and, after a successful step completion, **[build the missing dependencies manually](#31-build-missing-dependencies)**.
-**NOTE:** Kodi requires a compiler with C++14 support, i.e. gcc >= 4.9 or clang >= 3.4
+**NOTE:** Kodi requires a compiler with C++17 support, i.e. gcc >= 7 or clang >= 5
Install build dependencies:
```
@@ -168,6 +168,7 @@ Build a specific group of add-ons:
```
sudo gmake -j$(sysctl hw.ncpu | awk '{print $2}') -C tools/depends/target/binary-addons PREFIX=/usr/local ADDONS="pvr.*"
```
+For additional information on regular expression usage for ADDONS_TO_BUILD, view ADDONS_TO_BUILD section located at [Kodi add-ons CMake based buildsystem](../cmake/addons/README.md)
**NOTE:** `PREFIX=/usr/local` should match Kodi's `-DCMAKE_INSTALL_PREFIX=` prefix used in **[section 4.1](#41-configure-build)**.
diff --git a/docs/README.Linux.md b/docs/README.Linux.md
index e78f7b941e..83a9b729e6 100644
--- a/docs/README.Linux.md
+++ b/docs/README.Linux.md
@@ -72,9 +72,9 @@ git clone https://github.com/xbmc/xbmc kodi
## 3. Install the required packages
The following is the list of packages that are used to build Kodi on Debian/Ubuntu (with all supported external libraries enabled).
-**NOTE:** Kodi requires a compiler with C++14 support, i.e. gcc >= 4.9 or clang >= 3.4
+**NOTE:** Kodi requires a compiler with C++17 support, i.e. gcc >= 7 or clang >= 5
-* autoconf, automake, autopoint, gettext, autotools-dev, cmake, curl, default-jre | openjdk-6-jre | openjdk-7-jre, gawk, gcc (>= 4.9) | gcc-4.9, g++ (>= 4.9) | g++-4.9, cpp (>= 4.9) | cpp-4.9, flatbuffers, gdc, gperf, libasound2-dev | libasound-dev, libass-dev (>= 0.9.8), libavahi-client-dev, libavahi-common-dev, libbluetooth-dev, libbluray-dev, libbz2-dev, libcdio-dev, libcec4-dev | libcec-dev, libp8-platform-dev, libcrossguid-dev, libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev, libcwiid-dev, libdbus-1-dev, libegl1-mesa-dev, libenca-dev, libflac-dev, libfontconfig-dev, libfmt3-dev | libfmt-dev, libfreetype6-dev, libfribidi-dev, libfstrcmp-dev, libgcrypt-dev, libgif-dev (>= 5.0.5), libgles2-mesa-dev [armel] | libgl1-mesa-dev | libgl-dev, libglew-dev, libglu1-mesa-dev | libglu-dev, libgnutls-dev | libgnutls28-dev, libgpg-error-dev, libgtest-dev, libiso9660-dev, libjpeg-dev, liblcms2-dev, liblirc-dev, libltdl-dev, liblzo2-dev, libmicrohttpd-dev, libmysqlclient-dev, libnfs-dev, libogg-dev, libomxil-bellagio-dev [armel], libpcre3-dev, libplist-dev, libpng12-dev | libpng-dev, libpulse-dev, libshairplay-dev, libsmbclient-dev, libspdlog-dev, libsqlite3-dev, libssl-dev, libtag1-dev (>= 1.8) | libtag1x8, libtiff5-dev | libtiff-dev | libtiff4-dev, libtinyxml-dev, libtool, libudev-dev, libva-dev, libvdpau-dev, libvorbis-dev, libxkbcommon-dev, libxmu-dev, libxrandr-dev, libxslt1-dev | libxslt-dev, libxt-dev, waylandpp-dev | netcat, wayland-protocols | wipe, lsb-release, meson (>= 0.47.0), nasm (>= 2.14), ninja-build, python3-dev, python3-pil | python-imaging, python-support | python3-minimal, rapidjson-dev, swig, unzip, uuid-dev, yasm, zip, zlib1g-dev
+* autoconf, automake, autopoint, gettext, autotools-dev, cmake, curl, default-jre | openjdk-6-jre | openjdk-7-jre, gawk, gcc (>= 7) | gcc-7, g++ (>= 7) | g++-7, cpp (>= 7) | cpp-7, flatbuffers, gdc, gperf, libasound2-dev | libasound-dev, libass-dev (>= 0.9.8), libavahi-client-dev, libavahi-common-dev, libbluetooth-dev, libbluray-dev, libbz2-dev, libcdio-dev, libcec4-dev | libcec-dev, libp8-platform-dev, libcrossguid-dev, libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev, libcwiid-dev, libdbus-1-dev, libegl1-mesa-dev, libenca-dev, libflac-dev, libfontconfig-dev, libfmt3-dev | libfmt-dev, libfreetype6-dev, libfribidi-dev, libfstrcmp-dev, libgcrypt-dev, libgif-dev (>= 5.0.5), libgles2-mesa-dev [armel] | libgl1-mesa-dev | libgl-dev, libglew-dev, libglu1-mesa-dev | libglu-dev, libgnutls-dev | libgnutls28-dev, libgpg-error-dev, libgtest-dev, libiso9660-dev, libjpeg-dev, liblcms2-dev, liblirc-dev, libltdl-dev, liblzo2-dev, libmicrohttpd-dev, libmysqlclient-dev, libnfs-dev, libogg-dev, libomxil-bellagio-dev [armel], libpcre3-dev, libplist-dev, libpng12-dev | libpng-dev, libpulse-dev, libshairplay-dev, libsmbclient-dev, libspdlog-dev, libsqlite3-dev, libssl-dev, libtag1-dev (>= 1.8) | libtag1x8, libtiff5-dev | libtiff-dev | libtiff4-dev, libtinyxml-dev, libtool, libudev-dev, libva-dev, libvdpau-dev, libvorbis-dev, libxkbcommon-dev, libxmu-dev, libxrandr-dev, libxslt1-dev | libxslt-dev, libxt-dev, waylandpp-dev | netcat, wayland-protocols | wipe, lsb-release, meson (>= 0.47.0), nasm (>= 2.14), ninja-build, python3-dev, python3-pil | python-imaging, python-support | python3-minimal, rapidjson-dev, swig, unzip, uuid-dev, yasm, zip, zlib1g-dev
### 3.1. Build missing dependencies
Some packages may be missing or outdated in older distributions. Notably `crossguid`, `libfmt`, `libspdlog`, `waylandpp`, `wayland-protocols`, etc. are known to be outdated or missing. Fortunately there is an easy way to build individual dependencies with **[Kodi's unified depends build system](../tools/depends/README.md)**.
@@ -236,6 +236,7 @@ Build a specific group of add-ons:
```
sudo make -j$(getconf _NPROCESSORS_ONLN) -C tools/depends/target/binary-addons PREFIX=/usr/local ADDONS="pvr.*"
```
+For additional information on regular expression usage for ADDONS_TO_BUILD, view ADDONS_TO_BUILD section located here [Kodi add-ons CMake based buildsystem](../cmake/addons/README.md)
**NOTE:** `PREFIX=/usr/local` should match Kodi's `-DCMAKE_INSTALL_PREFIX=` prefix used in **[section 4.1](#41-configure-build)**.
diff --git a/docs/README.RaspberryPi.md b/docs/README.RaspberryPi.md
index 4d8ce4f0e6..d5a9141b24 100644
--- a/docs/README.RaspberryPi.md
+++ b/docs/README.RaspberryPi.md
@@ -1,242 +1,5 @@
![Kodi Logo](resources/banner_slim.png)
# Raspberry Pi build guide
-This guide has been tested with Ubuntu 16.04 (Xenial) x86_64 and 18.04 (Bionic). It is meant to cross-compile Kodi for the Raspberry Pi using **[Kodi's unified depends build system](../tools/depends/README.md)**. Please read it in full before you proceed to familiarize yourself with the build procedure.
-If you're looking to build Kodi natively using **[Raspbian](https://www.raspberrypi.org/downloads/raspbian/)**, you should follow the **[Ubuntu guide](README.Ubuntu.md)** instead. Several other distributions have **[specific guides](README.md)** and a general **[Linux guide](README.Linux.md)** is also available.
-
-## Table of Contents
-1. **[Document conventions](#1-document-conventions)**
-2. **[Install the required packages](#2-install-the-required-packages)**
-3. **[Get the source code](#3-get-the-source-code)**
- 3.1. **[Get Raspberry Pi tools and firmware](#31-get-raspberry-pi-tools-and-firmware)**
-4. **[Build tools and dependencies](#4-build-tools-and-dependencies)**
-5. **[Build Kodi](#5-build-kodi)**
-6. **[Docker](#6-docker)**
-7. **[Troubleshooting](#7-troubleshooting)**
- 7.1. **[ImportError: No module named \_sysconfigdata\_nd](#71-importerror-no-module-named-_sysconfigdata_nd)**
- 7.2. **[Errors connecting to any internet (TLS) service](#72-errors-connecting-to-any-internet-tls-service)**
-
-## 1. Document conventions
-This guide assumes you are using `terminal`, also known as `console`, `command-line` or simply `cli`. Commands need to be run at the terminal, one at a time and in the provided order.
-
-This is a comment that provides context:
-```
-this is a command
-this is another command
-and yet another one
-```
-
-**Example:** Clone Kodi's current master branch:
-```
-git clone https://github.com/xbmc/xbmc kodi
-```
-
-Commands that contain strings enclosed in angle brackets denote something you need to change to suit your needs.
-```
-git clone -b <branch-name> https://github.com/xbmc/xbmc kodi
-```
-
-**Example:** Clone Kodi's current Krypton branch:
-```
-git clone -b Krypton https://github.com/xbmc/xbmc kodi
-```
-
-Several different strategies are used to draw your attention to certain pieces of information. In order of how critical the information is, these items are marked as a note, tip, or warning. For example:
-
-**NOTE:** Linux is user friendly... It's just very particular about who its friends are.
-**TIP:** Algorithm is what developers call code they do not want to explain.
-**WARNING:** Developers don't change light bulbs. It's a hardware problem.
-
-**[back to top](#table-of-contents)** | **[back to section top](#1-document-conventions)**
-
-## 2. Install the required packages
-**NOTE:** Kodi requires a compiler with C++14 support, i.e. gcc >= 4.9 or clang >= 3.4
-
-Install build dependencies needed to cross-compile Kodi for the Raspberry Pi:
-```
-sudo apt install autoconf bison build-essential curl default-jdk gawk git gperf libcurl4-openssl-dev zlib1g-dev
-```
-
-**[back to top](#table-of-contents)**
-
-## 3. Get the source code
-Change to your `home` directory:
-```
-cd $HOME
-```
-
-Clone Kodi's current master branch:
-```
-git clone https://github.com/xbmc/xbmc kodi
-```
-
-### 3.1. Get Raspberry Pi tools and firmware
-Clone Raspberry Pi tools:
-```
-git clone https://github.com/raspberrypi/tools --depth=1
-```
-
-Clone Raspberry Pi firmware:
-```
-git clone https://github.com/raspberrypi/firmware --depth=1
-```
-
-**[back to top](#table-of-contents)**
-
-## 4. Build tools and dependencies
-Create target directory:
-```
-mkdir $HOME/kodi-rpi
-```
-
-Prepare to configure build:
-```
-cd $HOME/kodi/tools/depends
-./bootstrap
-```
-
-**TIP:** Look for comments starting with `Or ...` and only execute the command(s) you need.
-
-Configure build for Raspberry Pi 1:
-```
-./configure --host=arm-linux-gnueabihf --prefix=$HOME/kodi-rpi --with-toolchain=$HOME/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf --with-firmware=$HOME/firmware --with-platform=raspberry-pi --disable-debug
-```
-
-Or configure build for Raspberry Pi 2 and 3:
-```
-./configure --host=arm-linux-gnueabihf --prefix=$HOME/kodi-rpi --with-toolchain=$HOME/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf --with-firmware=$HOME/firmware --with-platform=raspberry-pi2 --disable-debug
-```
-
-Build tools and dependencies:
-```
-make -j$(getconf _NPROCESSORS_ONLN)
-```
-
-**TIP:** By adding `-j<number>` to the make command, you can choose how many concurrent jobs will be used and expedite the build process. It is recommended to use `-j$(getconf _NPROCESSORS_ONLN)` to compile on all available processor cores. The build machine can also be configured to do this automatically by adding `export MAKEFLAGS="-j$(getconf _NPROCESSORS_ONLN)"` to your shell config (e.g. `~/.bashrc`).
-
-**[back to top](#table-of-contents)** | **[back to section top](#4-build-tools-and-dependencies)**
-
-## 5. Build Kodi
-Configure CMake build:
-```
-cd $HOME/kodi
-make -C tools/depends/target/cmakebuildsys
-```
-
-**TIP:** BUILD_DIR can be provided as an argument to cmakebuildsys. This allows you to provide an alternate build location. Change all paths onwards as required if BUILD_DIR option used.
-```
-mkdir $HOME/kodi-build
-make -C tools/depends/target/cmakebuildsys BUILD_DIR=$HOME/kodi-build
-```
-
-Build Kodi:
-```
-cd $HOME/kodi/build
-make -j$(getconf _NPROCESSORS_ONLN)
-```
-
-Install to target directory:
-```
-make install
-```
-
-After the build process is finished, you can find the files ready to be installed inside `$HOME/kodi-rpi`. Look for a directory called `raspberry-pi-release` or `raspberry-pi2-release`.
-
-**[back to top](#table-of-contents)**
-
-
-## 6. Docker
-
-If you encounter issues with the previous instructions, or if you don't have a proper system for cross-compiling Kodi, it's also possible to use a [Docker](https://www.docker.com/) image to perform the build. This method, although it should work just like the build instructions mentioned above, is **not** supported. Therefore, issues related specifically to Docker should **not** be opened.
-
-Here is an example Dockerfile, summarizing basically all the instructions described above (/!\ may not be up to date with the actual instructions!). **Please read the comments as they describe things you NEED to change and/or consider before building.**
-
-```Dockerfile
-# Change 'latest' to the officially supported version of Ubuntu for cross-compilation
-FROM ubuntu:latest
-
-RUN apt-get update && apt-get upgrade -y
-RUN apt-get -y install autoconf bison build-essential curl default-jdk gawk git gperf libcurl4-openssl-dev zlib1g-dev file
-
-# The 'HOME' variable doesn't really matter - it is only the location of the files within the image
-ARG HOME=/home/pi
-# This is the location kodi will be built for, that means you will have to put the built files in
-# this directory afterwards. It is important because many paths end up hardcoded during the build.
-ARG PREFIX=/opt/kodi
-
-RUN mkdir $PREFIX
-WORKDIR $HOME
-
-# Replace 'master' with whichever branch/tag you wish to build - be careful with nightly builds!
-RUN git clone -b master https://github.com/xbmc/xbmc kodi --depth 1
-RUN git clone https://github.com/raspberrypi/tools --depth=1
-RUN git clone https://github.com/raspberrypi/firmware --depth=1
-
-WORKDIR $HOME/kodi/tools/depends
-RUN ./bootstrap
-
-# Change this if you're building on a RPi1, as described above
-RUN ./configure --host=arm-linux-gnueabihf --prefix=$PREFIX --with-toolchain=$HOME/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf --with-firmware=$HOME/firmware --with-platform=raspberry-pi2 --disable-debug
-
-RUN make -j$(getconf _NPROCESSORS_ONLN)
-
-WORKDIR $HOME/kodi
-# This step builds all the binary addons.
-# Kodi - at its core - works fine without them, however they are used by many other addons.
-# Therefore, it is recommended to simply compile all of them.
-RUN make -j$(getconf _NPROCESSORS_ONLN) -C tools/depends/target/binary-addons
-RUN make -C tools/depends/target/cmakebuildsys
-
-WORKDIR $HOME/kodi/build
-RUN make -j$(getconf _NPROCESSORS_ONLN)
-
-RUN make install
-RUN tar zfc /kodi.tar.gz $PREFIX
-```
-
-You can then build the image, and afterwards retrieve the build files from a dummy container:
-
-```bash
-docker build -t kodi_build .
-docker run --name some-temp-container-name kodi_build /bin/bash
-docker cp some-temp-container-name:/kodi.tar.gz ./
-docker rm some-temp-container-name
-```
-
-You should now have a file `kodi.tar.gz` in your current directory. Now you need to uncompress this file in the `$PREFIX` directory (as mentioned in the Dockerfile) of your Raspberry. Note that the archive contains multiple directories in its root, but only the `raspberry-pi2-release` (or `raspberry-pi-release`) is needed, so you can delete the others safely. If you encounter problems, please take a look at the [Troubleshooting](#7-troubleshooting) section below before filing an issue.
-
-**[back to top](#table-of-contents)**
-
-## 7. Troubleshooting
-
-### 7.1 ImportError: No module named \_sysconfigdata\_nd
-
-This is caused by an issue with a python package. The solution is to simply add a missing symlink so the library can be found, i.e.:
-
-```bash
-ln -s /usr/lib/python2.7/plat-arm-linux-gnueabihf/_sysconfigdata_nd.py /usr/lib/python2.7/
-```
-
-### 7.2 Errors connecting to any internet (TLS) service
-
-First, you should enable debug logging (instructions [here](https://kodi.wiki/view/Log_file)). Then you need to check the logs and find what the source of your problem is. If, when trying to access TLS services (e.g. when installing an addon), the connection fails and your log contains entries such as:
-
-```log
-# note that those logs appear when enabling component-specific logs -> libcurl
-2019-05-19 17:18:39.570 T:1854288832 DEBUG: Curl::Debug - TEXT: SSL certificate problem: unable to get local issuer certificate
-2019-05-19 17:18:39.570 T:1854288832 DEBUG: Curl::Debug - TEXT: Closing connection 0
-
-# this is part of the regular Kodi logs
-2019-05-19 17:18:39.570 T:1854288832 ERROR: CCurlFile::FillBuffer - Failed: Peer certificate cannot be authenticated with given CA certificates(60)
-```
-
-Then, you need to define the environment variable `SSL_CERT_FILE` so it points to your system's certificate file. Depending on how you start Kodi, putting this line in your in your `.profile` file should fix this issue:
-
-```bash
-export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
-```
-
-Note that you need to define this variable *before* starting Kodi. For example, if you start Kodi on startup through a crontab, your `.profile` will *not* be sourced.
-
-**[back to top](#table-of-contents)**
+The Raspberry Pi platform has been merged into the GBM build. See [README.Linux.md](README.Linux.md).
diff --git a/docs/README.Ubuntu.md b/docs/README.Ubuntu.md
index bd41189b69..3de2cacaa5 100644
--- a/docs/README.Ubuntu.md
+++ b/docs/README.Ubuntu.md
@@ -112,7 +112,7 @@ sudo apt install distcc
### 3.2. Get build dependencies manually
If you get a `package not found` type of message with the below command, remove the offending package(s) from the install list and reissue the command. Take a note of the missing dependencies and, after a successful step completion, **[build the missing dependencies manually](README.Linux.md#31-build-missing-dependencies)**.
-**NOTE:** Kodi requires a compiler with C++14 support, i.e. gcc >= 4.9 or clang >= 3.4
+**NOTE:** Kodi requires a compiler with C++17 support, i.e. gcc >= 7 or clang >= 5
Install build dependencies manually:
```
diff --git a/docs/README.Windows.md b/docs/README.Windows.md
index 19e0688f4b..f6a6ea65a6 100644
--- a/docs/README.Windows.md
+++ b/docs/README.Windows.md
@@ -176,7 +176,7 @@ BuildSetup.bat
*Normal* 32bit and 64bit builds generate an `exe` file ready to run, located at `%userprofile%\kodi\kodi-build\Debug` or `%userprofile%\kodi\kodi-build\Release`, depending on the build config. An installer `exe` file, located at `%userprofile%\kodi\project\Win32BuildSetup`, is also generated.
-UWP builds generate `appx`, `appxsym` and `cer` files, located at `%userprofile%\kodi\`. You can install them following this **[guide](https://kodi.wiki/view/HOW-TO:Install_Kodi_for_Universal_Windows_Platform)**.
+UWP builds generate `msix`, `appxsym` and `cer` files, located at `%userprofile%\kodi\project\UWPBuildSetup`. You can install them following this **[guide](https://kodi.wiki/view/HOW-TO:Install_Kodi_for_Universal_Windows_Platform)**.
**[back to top](#table-of-contents)**
@@ -235,7 +235,7 @@ cmake --build . --config "Release"
```
*Normal* 32bit and 64bit builds generate an `exe` file ready to run, located at `%userprofile%\kodi-build\Debug` or `%userprofile%\kodi-build\Release`, depending on the build config.
-UWP builds generate `appx`, `appxsym` and `cer` files, located inside directories at `%userprofile%\kodi-build\AppPackages\kodi\`. You can install them following this **[guide](https://kodi.wiki/view/HOW-TO:Install_Kodi_for_Universal_Windows_Platform)**.
+UWP builds generate `msix`, `appxsym` and `cer` files, located inside directories at `%userprofile%\kodi-build\AppPackages\kodi\`. You can install them following this **[guide](https://kodi.wiki/view/HOW-TO:Install_Kodi_for_Universal_Windows_Platform)**.
**[back to top](#table-of-contents)** | **[back to section top](#6-build-kodi-manually)**
diff --git a/docs/README.iOS.md b/docs/README.iOS.md
index da03618f55..85052b655f 100644
--- a/docs/README.iOS.md
+++ b/docs/README.iOS.md
@@ -130,6 +130,7 @@ Build a specific group of add-ons:
```
make -j$(getconf _NPROCESSORS_ONLN) -C tools/depends/target/binary-addons ADDONS="pvr.*"
```
+For additional information on regular expression usage for ADDONS_TO_BUILD, view ADDONS_TO_BUILD section located here [Kodi add-ons CMake based buildsystem](../cmake/addons/README.md)
## 5.2. Xcode project building
@@ -146,9 +147,7 @@ Generate Xcode project to build a specific group of add-ons:
make -C tools/depends/target/cmakebuildsys CMAKE_EXTRA_ARGUMENTS="-DENABLE_XCODE_ADDONBUILD=ON -DADDONS_TO_BUILD='pvr.*'"
```
-**TIP:** When using addontype.* for -DADDONS_TO_BUILD argument, you cannot have multiple
-addon types. ie -DADDONS_TO_BUILD='game.libretro.* peripheral.*' is not valid. You will
-need to individually list the addons as per the first example for specific addon building.
+For additional information on regular expression usage for ADDONS_TO_BUILD, view ADDONS_TO_BUILD section located at [Kodi add-ons CMake based buildsystem](../cmake/addons/README.md)
Generate Xcode project to build all add-ons automatically:
```sh
diff --git a/docs/README.macOS.md b/docs/README.macOS.md
index 1138651018..a8347384ce 100644
--- a/docs/README.macOS.md
+++ b/docs/README.macOS.md
@@ -131,6 +131,7 @@ OR
```
make -j$(getconf _NPROCESSORS_ONLN) -C tools/depends/target/binary-addons ADDONS="pvr.*"
```
+For additional information on regular expression usage for ADDONS_TO_BUILD, view ADDONS_TO_BUILD section located at [Kodi add-ons CMake based buildsystem](../cmake/addons/README.md)
**[back to top](#table-of-contents)**
diff --git a/docs/README.md b/docs/README.md
index 3c033f8435..836f1c39a8 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -16,7 +16,6 @@ Kodi uses CMake as its building system but instructions are highly dependent on
<a href="README.Linux.md" title="Linux"><img src="resources/linux.svg" height="78"></a>
<a href="README.macOS.md" title="macOS"><img src="resources/macos.svg" height="78"></a>
<a href="README.openSUSE.md" title="openSUSE"><img src="resources/opensuse.svg" height="78"></a>
- <a href="README.RaspberryPi.md" title="Raspberry Pi"><img src="resources/raspberrypi.svg" height="78"></a>
<a href="README.tvOS.md" title="tvOS"><img src="resources/tvos.svg" height="78"></a>
<a href="README.Ubuntu.md" title="Ubuntu"><img src="resources/ubuntu.svg" height="78"></a>
<a href="README.Windows.md" title="Windows"><img src="resources/windows.svg" height="78"></a>
diff --git a/docs/README.openSUSE.md b/docs/README.openSUSE.md
index f33975918b..98e8182fce 100644
--- a/docs/README.openSUSE.md
+++ b/docs/README.openSUSE.md
@@ -72,7 +72,7 @@ sudo zypper ref
If you get a `package not found` type of message with the below command, remove the offending package(s) from the install list and reissue the command. Take a note of the missing dependencies and, after a successful step completion, **[build the missing dependencies manually](#31-build-missing-dependencies)**.
-**NOTE:** Kodi requires a compiler with C++14 support, i.e. gcc >= 4.9 or clang >= 3.4
+**NOTE:** Kodi requires a compiler with C++17 support, i.e. gcc >= 7 or clang >= 5
Install build dependencies:
```
diff --git a/docs/README.tvOS.md b/docs/README.tvOS.md
index 2e938cf40d..483b613840 100644
--- a/docs/README.tvOS.md
+++ b/docs/README.tvOS.md
@@ -161,6 +161,7 @@ Generate Xcode project to build a specific group of add-ons:
```
make -C tools/depends/target/cmakebuildsys CMAKE_EXTRA_ARGUMENTS="-DENABLE_XCODE_ADDONBUILD=ON -DADDONS_TO_BUILD='pvr.*'"
```
+For additional information on regular expression usage for ADDONS_TO_BUILD, view ADDONS_TO_BUILD section located at [Kodi add-ons CMake based buildsystem](../cmake/addons/README.md)
Generate Xcode project to build all add-ons automatically:
```
diff --git a/docs/resources/raspberrypi.svg b/docs/resources/raspberrypi.svg
deleted file mode 100644
index b1121fb85f..0000000000
--- a/docs/resources/raspberrypi.svg
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
- <rdf:RDF>
- <cc:Work rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
- <dc:title/>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <rect x="-1.4211e-14" y="8.5449e-6" width="26.458" height="26.458" fill="#c51a4a" stroke-width=".27763"/>
- <path d="m9.9286 3.97c-0.093646 3e-3 -0.19449 0.0375-0.30893 0.12775-0.2802-0.10803-0.55196-0.14559-0.79495 0.0744-0.37521-0.0487-0.49712 0.0518-0.58952 0.16905-0.082373-2e-3 -0.61632-0.0847-0.86123 0.2806-0.61536-0.0728-0.80985 0.36195-0.58947 0.76742-0.12571 0.19454-0.25596 0.38676 0.037957 0.75772-0.10396 0.20656-0.039487 0.43068 0.20542 0.70187-0.06464 0.29046 0.062431 0.49532 0.29034 0.65502-0.042659 0.39742 0.36444 0.6285 0.48596 0.71082 0.046682 0.23154 0.14395 0.4501 0.6089 0.57089 0.076707 0.34512 0.35612 0.40472 0.62675 0.47713-0.89437 0.5199-1.6613 1.2039-1.6561 2.8822l-0.13104 0.2337c-1.0255 0.62363-1.9482 2.6281-0.50534 4.2573 0.094213 0.50999 0.25227 0.8763 0.393 1.2817 0.21046 1.6336 1.5841 2.3986 1.9465 2.4891 0.53089 0.40438 1.0963 0.78809 1.8615 1.0569 0.7213 0.7439 1.5028 1.0274 2.2885 1.027 0.01156 0 1.602-0.28303 2.3233-1.027 0.76515-0.26882 1.3306-0.65253 1.8615-1.0569 0.36229-0.0905 1.7359-0.85546 1.9464-2.4891 0.14072-0.40541 0.29878-0.77172 0.39306-1.2817 1.4427-1.6294 0.52012-3.6339-0.5054-4.2576l-0.13121-0.23369c0.0052-1.6782-0.76175-2.3622-1.6561-2.8822 0.27057-0.0724 0.55004-0.132 0.62669-0.47713 0.46495-0.12084 0.56228-0.33935 0.6089-0.57089 0.12158-0.0823 0.52862-0.3134 0.48602-0.71082 0.22786-0.1597 0.35493-0.36461 0.29029-0.65501 0.24496-0.2712 0.30938-0.49532 0.20542-0.70193 0.29397-0.37073 0.16356-0.56296 0.03801-0.7575 0.22026-0.40546 0.02589-0.84027-0.5897-0.76742-0.2448-0.36529-0.77863-0.28235-0.86123-0.28065-0.09234-0.11722-0.21426-0.21766-0.58947-0.169-0.24298-0.21998-0.51469-0.18247-0.79495-0.0744-0.33278-0.26259-0.55298-0.0521-0.80452 0.0275-0.40286-0.13166-0.49503 0.0487-0.69297 0.12215-0.4394-0.0929-0.57293 0.10928-0.78356 0.32263l-0.24502-5e-3c-0.66272 0.39056-0.99198 1.1858-1.1087 1.5947-0.11676-0.40891-0.44523-1.2042-1.1078-1.5947l-0.24502 5e-3c-0.21092-0.21335-0.34439-0.41549-0.78379-0.32263-0.198-0.0735-0.28983-0.25381-0.69303-0.12215-0.16508-0.0522-0.31691-0.16078-0.49565-0.15522l-4.5488 7.9878" fill="#ffffff" stroke-width=".056652"/>
- <g transform="translate(0,-270.54)" fill="#c51a4a" stroke-width=".056652">
- <path d="m8.6091 276.23c1.7583 0.9065 2.7804 1.6398 3.3405 2.2643-0.28678 1.1494-1.7829 1.2019-2.3299 1.1696 0.112-0.0521 0.20548-0.1146 0.23862-0.21052-0.13727-0.0976-0.62397-0.0103-0.96377-0.20117 0.13053-0.0271 0.1916-0.0534 0.25261-0.14973-0.32099-0.10237-0.6668-0.19064-0.87018-0.36026 0.10974 1e-3 0.21222 0.0246 0.35555-0.0748-0.28751-0.15495-0.59434-0.27777-0.83273-0.51464 0.14866-4e-3 0.30893-1e-3 0.35555-0.0561-0.26315-0.16305-0.48523-0.34433-0.66901-0.54267 0.20803 0.0251 0.2959 4e-3 0.3462-0.0328-0.19896-0.20378-0.45073-0.37583-0.57077-0.62692 0.15443 0.0533 0.29578 0.0736 0.39764-5e-3 -0.067586-0.15251-0.35719-0.24248-0.52398-0.59888 0.16265 0.0158 0.3351 0.0355 0.3696 0-0.075461-0.30751-0.20497-0.48041-0.33198-0.65955 0.34802-5e-3 0.87534 1e-3 0.85149-0.028l-0.21522-0.21987c0.33997-0.0915 0.68782 0.0147 0.94037 0.0935 0.11336-0.0895-0.00204-0.20259-0.14038-0.31811 0.28893 0.0386 0.54998 0.10498 0.786 0.19647 0.12605-0.11381-0.081863-0.22768-0.18248-0.3415 0.44636 0.0846 0.63547 0.20367 0.82339 0.32281 0.13636-0.1307 0.0078-0.2418-0.084185-0.35555 0.33657 0.12463 0.50993 0.28558 0.6924 0.44444 0.06186-0.0835 0.15721-0.14475 0.04209-0.34621 0.23896 0.13772 0.41894 0.30003 0.55208 0.48189 0.14786-0.0942 0.08809-0.22287 0.08889-0.34156 0.24836 0.20202 0.40597 0.41702 0.59887 0.62692 0.03886-0.0283 0.07286-0.12424 0.10294-0.27601 0.59241 0.57474 1.4296 2.0225 0.21516 2.5965-1.0335-0.8524-2.2679-1.472-3.6357-1.9368l3.966e-4 -2.3e-4"/>
- <path d="m17.939 276.23c-1.758 0.90661-2.7802 1.6397-3.3402 2.2643 0.28678 1.1494 1.7828 1.2019 2.3298 1.1696-0.112-0.0521-0.20548-0.1146-0.23856-0.21052 0.13727-0.0976 0.62397-0.0103 0.96371-0.20117-0.13053-0.0271-0.19154-0.0534-0.25261-0.14973 0.32105-0.10237 0.66686-0.19064 0.87018-0.36026-0.10974 1e-3 -0.21222 0.0246-0.35555-0.0748 0.28757-0.15495 0.5944-0.27777 0.83279-0.51464-0.14871-4e-3 -0.30898-1e-3 -0.35555-0.0561 0.26315-0.16305 0.48523-0.34433 0.66901-0.54267-0.20808 0.0251-0.2959 4e-3 -0.3462-0.0328 0.19891-0.20378 0.45073-0.37583 0.57077-0.62692-0.15449 0.0533-0.29584 0.0736-0.3977-5e-3 0.06759-0.15251 0.35725-0.24248 0.52398-0.59888-0.16259 0.0158-0.3351 0.0355-0.3696 0 0.07563-0.30762 0.20514-0.48052 0.33215-0.65966-0.34802-5e-3 -0.87534 1e-3 -0.85149-0.028l0.21522-0.21993c-0.33997-0.0915-0.68782 0.0147-0.94037 0.0936-0.11336-0.0894 2e-3 -0.20259 0.14033-0.3181-0.28887 0.0385-0.54998 0.10498-0.78594 0.19647-0.12611-0.11382 0.08186-0.22769 0.18248-0.3415-0.44636 0.0846-0.63547 0.20366-0.82344 0.3228-0.13636-0.13069-0.0078-0.24179 0.08424-0.35555-0.33657 0.12464-0.50993 0.28559-0.6924 0.44444-0.06192-0.0835-0.15721-0.14474-0.04215-0.3462-0.2389 0.13772-0.41889 0.30003-0.55202 0.48189-0.14786-0.0942-0.08809-0.22293-0.08889-0.34156-0.24836 0.20202-0.40597 0.41696-0.59887 0.62691-0.03886-0.0283-0.07286-0.12423-0.10294-0.27606-0.59241 0.57479-1.4296 2.0226-0.21516 2.5966 1.0329-0.85262 2.2672-1.4721 3.6352-1.9369h-2.26e-4"/>
- <path d="m15.403 287.93c0.0061 1.0726-0.93188 1.9467-2.095 1.9523-1.1632 6e-3 -2.1111-0.85924-2.1172-1.9318-5.6e-5 -7e-3 -5.6e-5 -0.0136 0-0.0204-0.0061-1.0726 0.93182-1.9466 2.095-1.9523 1.1632-6e-3 2.111 0.85925 2.1172 1.9318v0.0205"/>
- <path d="m12.078 282.39c0.87267 0.5718 1.03 1.8678 0.35136 2.8947s-1.9362 1.396-2.8089 0.82423c-0.87267-0.57179-1.0299-1.8678-0.35136-2.8947 0.67864-1.0269 1.9362-1.396 2.8089-0.82424"/>
- <path d="m14.434 282.28c-0.87262 0.57174-1.0299 1.8678-0.35136 2.8947 0.67864 1.0269 1.9362 1.396 2.8089 0.82418 0.87267-0.57174 1.03-1.8677 0.35136-2.8947-0.67858-1.0269-1.9362-1.3959-2.8089-0.82418"/>
- <path d="m7.7169 283.32c0.94219-0.25256 0.3181 3.8979-0.44852 3.5573-0.84327-0.67825-1.1149-2.6645 0.44852-3.5573"/>
- <path d="m18.605 283.27c-0.9423-0.2525-0.3181 3.8981 0.44852 3.5576 0.84327-0.6783 1.1149-2.6648-0.44852-3.5576"/>
- <path d="m15.404 280.18c1.626-0.27454 2.979 0.6915 2.9243 2.4546-0.05348 0.67598-3.5234-2.354-2.9243-2.4546"/>
- <path d="m10.911 280.13c-1.6261-0.2746-2.979 0.69167-2.9243 2.4547 0.05348 0.67592 3.5234-2.354 2.9243-2.4547"/>
- <path d="m13.247 279.71c-0.97046-0.0253-1.9018 0.72023-1.9041 1.1527-0.0027 0.52539 0.7673 1.0634 1.9107 1.077 1.1676 8e-3 1.9127-0.43062 1.9164-0.97284 0.0043-0.61434-1.0619-1.2664-1.9231-1.2569v5e-5"/>
- <path d="m13.306 290.49c0.8461-0.0369 1.9814 0.2725 1.9837 0.68306 0.01405 0.39861-1.0297 1.2993-2.0398 1.2819-1.0461 0.0451-2.0719-0.85693-2.0585-1.1696-0.01569-0.45843 1.2738-0.81636 2.1146-0.79534"/>
- <path d="m10.181 288.06c0.60238 0.72572 0.87704 2.0008 0.3743 2.3766-0.4756 0.28694-1.6306 0.16876-2.4515-1.0106-0.55366-0.98961-0.48234-1.9966-0.09359-2.2924 0.58131-0.35408 1.4795 0.12424 2.1708 0.92638h-5.7e-5"/>
- <path d="m16.311 287.83c-0.65179 0.76339-1.0147 2.1558-0.53927 2.6043 0.45464 0.34841 1.675 0.29969 2.5765-0.95114 0.65456-0.8401 0.43526-2.2431 0.06135-2.6156-0.55542-0.4296-1.3528 0.12022-2.0986 0.9623v2.3e-4"/>
- </g>
-</svg>
diff --git a/system/keymaps/customcontroller.SiriRemote.xml b/system/keymaps/customcontroller.SiriRemote.xml
index f555d40292..aa30481dbd 100644
--- a/system/keymaps/customcontroller.SiriRemote.xml
+++ b/system/keymaps/customcontroller.SiriRemote.xml
@@ -128,7 +128,7 @@
</VideoMenu>
<Videos>
<customcontroller name="SiriRemote">
- <button id="7">Info</button>
+ <button id="7">ContextMenu</button>
</customcontroller>
</Videos>
<PictureInfo>
diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml
deleted file mode 100644
index f6c228253d..0000000000
--- a/system/settings/rbp.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<settings version="1">
- <section id="player">
- <category id="videoplayer">
- <group id="3">
- <setting id="videoplayer.rendermethod">
- <visible>false</visible>
- </setting>
- <setting id="videoplayer.hqscalers">
- <visible>false</visible>
- </setting>
- <setting id="videoplayer.usemmal" type="boolean" label="36434" help="36435">
- <level>2</level>
- <default>true</default>
- <control type="toggle" />
- </setting>
- <setting id="videoplayer.limitguiupdate" type="integer" label="38013" help="38014">
- <level>2</level>
- <default>10</default>
- <constraints>
- <minimum label="38015">0</minimum> <!-- Unlimited -->
- <step>5</step>
- <maximum>25</maximum>
- </constraints>
- <control type="spinner" format="string">
- <formatlabel>38016</formatlabel>
- </control>
- <control type="edit" format="integer" />
- </setting>
- </group>
- <group id="4">
- <setting id="videoplayer.supportmvc" type="boolean" label="38027" help="38028">
- <level>2</level>
- <default>true</default>
- <control type="toggle" />
- </setting>
- </group>
- </category>
- </section>
- <section id="media">
- <category id="video">
- <group id="1">
- <setting id="myvideos.extractchapterthumbs">
- <default>false</default>
- </setting>
- </group>
- </category>
- </section>
- <section id="system">
- <category id="display">
- <group id="1">
- <setting id="videoscreen.screen">
- <visible>false</visible>
- </setting>
- <setting id="videoscreen.blankdisplays">
- <visible>false</visible>
- </setting>
- <setting id="videoscreen.fakefullscreen">
- <visible>false</visible>
- </setting>
- <setting id="videoscreen.textures32" type="boolean" label="37020" help="36547">
- <level>2</level>
- <default>false</default>
- <control type="toggle" />
- </setting>
- <setting id="videoscreen.limitgui" type="integer" label="37021" help="36548">
- <level>2</level>
- <default>0</default>
- <constraints>
- <options>
- <option label="37026">0</option> <!-- auto -->
- <option label="37027">540</option> <!-- 540 -->
- <option label="37028">720</option> <!-- 720 -->
- <option label="37029">900</option> <!-- 900 -->
- <option label="37030">1080</option> <!-- unlimited -->
- </options>
- </constraints>
- <control type="spinner" format="string" />
- <control type="edit" format="integer" />
- </setting>
- </group>
- <group id="2">
- <setting id="videoscreen.framepacking" type="boolean" label="38029" help="38030">
- <level>2</level>
- <default>false</default>
- <control type="toggle" />
- </setting>
- </group>
- </category>
- <category id="audio">
- <group id="1">
- <setting id="audiooutput.processquality">
- <default>101</default> <!-- AE_QUALITY_GPU -->
- </setting>
- <setting id="audiooutput.atempothreshold">
- <default>100</default> <!-- disabled -->
- </setting>
- <setting id="audiooutput.audiodevice">
- <default>PI:HDMI</default>
- </setting>
- </group>
- <group id="3">
- <setting id="audiooutput.ac3transcode" help="37024">
- </setting>
- </group>
- </category>
- <category id="input">
- <group id="4" label="35150">
- <setting id="input.libinputkeyboardlayout" type="string" label="310" help="36436">
- <level>0</level>
- <default>us</default>
- <visible>true</visible>
- <constraints>
- <options>libinputkeyboardlayout</options>
- </constraints>
- <control type="list" format="string">
- <multiselect>false</multiselect>
- </control>
- </setting>
- </group>
- </category>
- </section>
-</settings>
diff --git a/system/settings/rbp2.xml b/system/settings/rbp2.xml
deleted file mode 100644
index 44a982453d..0000000000
--- a/system/settings/rbp2.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<settings version="1">
- <section id="system">
- <category id="display">
- <group id="1">
- <setting id="videoscreen.textures32">
- <default>true</default>
- </setting>
- </group>
- </category>
- <category id="audio">
- <group id="1">
- <setting id="audiooutput.atempothreshold">
- <default>2</default> <!-- 2% -->
- </setting>
- </group>
- <group id="3">
- <setting id="audiooutput.ac3transcode" help="36429">
- </setting>
- </group>
- <group id="1">
- <setting id="audiooutput.processquality">
- <default>30</default> <!-- AE_QUALITY_MID -->
- </setting>
- </group>
- </category>
- </section>
-</settings>
diff --git a/system/settings/wayland.xml b/system/settings/wayland.xml
index 2e214fc5ea..6fcc42ad48 100644
--- a/system/settings/wayland.xml
+++ b/system/settings/wayland.xml
@@ -1,5 +1,43 @@
<?xml version="1.0" encoding="utf-8" ?>
<settings version="1">
+ <section id="player">
+ <category id="videoplayer">
+ <group id="3">
+ <setting id="videoplayer.useprimedecoder" type="boolean" label="13430" help="36172">
+ <requirement>HAS_GLES</requirement>
+ <visible>false</visible>
+ <level>2</level>
+ <default>false</default>
+ <control type="toggle" />
+ </setting>
+ <setting id="videoplayer.useprimedecoderforhw" type="boolean" parent="videoplayer.useprimedecoder" label="13438" help="36172">
+ <requirement>HAS_GLES</requirement>
+ <visible>true</visible>
+ <dependencies>
+ <dependency type="enable">
+ <condition setting="videoplayer.useprimedecoder" operator="is">true</condition>
+ </dependency>
+ </dependencies>
+ <level>3</level>
+ <default>true</default>
+ <control type="toggle" />
+ </setting>
+ <setting id="videoplayer.useprimerenderer" type="integer" label="13462" help="13463">
+ <requirement>HAS_GLES</requirement>
+ <visible>false</visible>
+ <level>2</level>
+ <default>1</default>
+ <constraints>
+ <options>
+ <option label="13464">0</option> <!-- DIRECT -->
+ <option label="13465">1</option> <!-- GLES -->
+ </options>
+ </constraints>
+ <control type="spinner" format="string" />
+ </setting>
+ </group>
+ </category>
+ </section>
<section id="system">
<category id="display">
<group id="1">
@@ -11,4 +49,4 @@
</group>
</category>
</section>
-</settings> \ No newline at end of file
+</settings>
diff --git a/tools/buildsteps/defaultenv b/tools/buildsteps/defaultenv
index becf6ae8f8..66f0777fb0 100644
--- a/tools/buildsteps/defaultenv
+++ b/tools/buildsteps/defaultenv
@@ -50,12 +50,6 @@ case $XBMC_PLATFORM_DIR in
DEFAULT_CONFIGURATION="Debug"
;;
- rbpi)
- JENKINS_RBPI_DEVENV=${JENKINS_RBPI_DEVENV:-"/home/jenkins/rbpi-dev"}
- DEFAULT_XBMC_DEPENDS_ROOT=$WORKSPACE/tools/depends/xbmc-depends
- DEFAULT_CONFIGURATION="Debug"
- ;;
-
freebsd)
DEFAULT_CONFIGURATION="Debug"
;;
diff --git a/tools/buildsteps/linux-arm-gbm/configure-depends b/tools/buildsteps/linux-arm-gbm/configure-depends
new file mode 100644
index 0000000000..8ffc695d80
--- /dev/null
+++ b/tools/buildsteps/linux-arm-gbm/configure-depends
@@ -0,0 +1,9 @@
+WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
+XBMC_PLATFORM_DIR=linux-arm-gbm
+. $WORKSPACE/tools/buildsteps/defaultenv
+
+if [ "$(pathChanged $WORKSPACE/tools/depends)" == "1" ]
+then
+ cd $WORKSPACE/tools/depends;./configure \
+ --with-toolchain=/usr --prefix=$XBMC_DEPENDS_ROOT --host=arm-linux-gnueabihf --with-platform=gbm --with-tarballs=$TARBALLS $DEBUG_SWITCH
+fi
diff --git a/tools/buildsteps/rbpi/configure-xbmc b/tools/buildsteps/linux-arm-gbm/configure-xbmc
index 6dd54bf845..72f3c3a7dc 100755..100644
--- a/tools/buildsteps/rbpi/configure-xbmc
+++ b/tools/buildsteps/linux-arm-gbm/configure-xbmc
@@ -1,5 +1,5 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
make -C $WORKSPACE/tools/depends/target/cmakebuildsys
diff --git a/tools/buildsteps/rbpi/make-binary-addons b/tools/buildsteps/linux-arm-gbm/make-binary-addons
index 862e7d79e9..fbc9822d53 100755..100644
--- a/tools/buildsteps/rbpi/make-binary-addons
+++ b/tools/buildsteps/linux-arm-gbm/make-binary-addons
@@ -1,5 +1,5 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
. $WORKSPACE/tools/buildsteps/$XBMC_PLATFORM_DIR/make-native-depends
diff --git a/tools/buildsteps/rbpi/make-depends b/tools/buildsteps/linux-arm-gbm/make-depends
index ceeee09234..004eed0738 100755..100644
--- a/tools/buildsteps/rbpi/make-depends
+++ b/tools/buildsteps/linux-arm-gbm/make-depends
@@ -1,9 +1,8 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
if [ "$(pathChanged $WORKSPACE/tools/depends)" == "1" ]
then
cd $WORKSPACE/tools/depends;make -j $BUILDTHREADS || make && tagSuccessFulBuild $WORKSPACE/tools/depends
fi
-
diff --git a/tools/buildsteps/rbpi/make-native-depends b/tools/buildsteps/linux-arm-gbm/make-native-depends
index d4d9e7dbe1..d15bfd4f8b 100755..100644
--- a/tools/buildsteps/rbpi/make-native-depends
+++ b/tools/buildsteps/linux-arm-gbm/make-native-depends
@@ -1,9 +1,9 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
if [ "$(pathChanged $WORKSPACE/tools/depends)" == "1" ] && [ "$BINARY_ADDONS_CLEAN_NATIVETOOLS" != "0" ]
then
git clean -xffd $WORKSPACE/tools/depends/native
cd $WORKSPACE/tools/depends/native;make -j $BUILDTHREADS && tagSuccessFulBuild $WORKSPACE/tools/depends
-fi \ No newline at end of file
+fi
diff --git a/tools/buildsteps/rbpi/make-xbmc b/tools/buildsteps/linux-arm-gbm/make-xbmc
index 07cfae21c7..089d88d026 100755..100644
--- a/tools/buildsteps/rbpi/make-xbmc
+++ b/tools/buildsteps/linux-arm-gbm/make-xbmc
@@ -1,5 +1,5 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
cd $WORKSPACE/build;make -j$BUILDTHREADS || make
diff --git a/tools/buildsteps/rbpi/package b/tools/buildsteps/linux-arm-gbm/package
index f3c41a5c96..5032c912e0 100755..100644
--- a/tools/buildsteps/rbpi/package
+++ b/tools/buildsteps/linux-arm-gbm/package
@@ -1,5 +1,5 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
-#nothing for rbpi atm
+#nothing for linux atm
diff --git a/tools/buildsteps/rbpi/prepare-depends b/tools/buildsteps/linux-arm-gbm/prepare-depends
index c38eb77901..dc62bbe2a5 100755..100644
--- a/tools/buildsteps/rbpi/prepare-depends
+++ b/tools/buildsteps/linux-arm-gbm/prepare-depends
@@ -1,20 +1,11 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
#clean without depends for skipping depends build if possible
#also skip binary addons (pvr, audioencoder) as long as they are deployed in tree
cd $WORKSPACE;git clean -xfd -e "cmake/.last_success_revision" -e "tools/depends" ${DEPLOYED_BINARY_ADDONS}
-if [ -d $JENKINS_RBPI_DEVENV/firmware ]
-then
- cd $JENKINS_RBPI_DEVENV/firmware;git pull origin master
-else
- cd $JENKINS_RBPI_DEVENV;git clone git://github.com/raspberrypi/firmware.git --depth=1 -b master
-fi
-
-cd $WORKSPACE
-
# if depends path has changed - cleanout everything and do a full rebuild
if [ "$(pathChanged $WORKSPACE/tools/depends)" == "1" ]
then
diff --git a/tools/buildsteps/rbpi/prepare-xbmc b/tools/buildsteps/linux-arm-gbm/prepare-xbmc
index 3957f5aab7..73c1b53056 100755..100644
--- a/tools/buildsteps/rbpi/prepare-xbmc
+++ b/tools/buildsteps/linux-arm-gbm/prepare-xbmc
@@ -1,9 +1,7 @@
WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
+XBMC_PLATFORM_DIR=linux-arm-gbm
. $WORKSPACE/tools/buildsteps/defaultenv
-cd $WORKSPACE
-
#build binary addons before building xbmc...
#make sure that binary_addons don't clean the native tools
#here
diff --git a/tools/buildsteps/linux-arm-gbm/run-tests b/tools/buildsteps/linux-arm-gbm/run-tests
new file mode 100644
index 0000000000..b76ec0e0fb
--- /dev/null
+++ b/tools/buildsteps/linux-arm-gbm/run-tests
@@ -0,0 +1,14 @@
+WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
+XBMC_PLATFORM_DIR=linux-arm-gbm
+. $WORKSPACE/tools/buildsteps/defaultenv
+
+cd $WORKSPACE/build;make -j$BUILDTHREADS kodi-test
+if [ "$Configuration" != "Coverage" ]; then
+ cd $WORKSPACE;build/kodi-test --gtest_output=xml:gtestresults.xml
+else
+ cd $WORKSPACE/build;GTEST_OUTPUT="xml:$WORKSPACE/gtestresults.xml" make coverage
+fi
+
+awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml
+rm gtestresults.xml
+mv gtestresults-skipped.xml gtestresults.xml
diff --git a/tools/buildsteps/rbpi/configure-depends b/tools/buildsteps/rbpi/configure-depends
deleted file mode 100755
index 13d5ca27cb..0000000000
--- a/tools/buildsteps/rbpi/configure-depends
+++ /dev/null
@@ -1,12 +0,0 @@
-WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
-XBMC_PLATFORM_DIR=rbpi
-. $WORKSPACE/tools/buildsteps/defaultenv
-
-if [ "$(pathChanged $WORKSPACE/tools/depends)" == "1" ]
-then
- cd $WORKSPACE/tools/depends;
-
- ./configure --with-platform=raspberry-pi2 --host=arm-linux-gnueabihf --prefix=$XBMC_DEPENDS_ROOT --with-tarballs=$TARBALLS \
- --with-firmware=$JENKINS_RBPI_DEVENV/firmware --build=i686-linux $DEBUG_SWITCH \
- --with-toolchain=$JENKINS_RBPI_DEVENV/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf
-fi
diff --git a/tools/buildsteps/windows/BuildSetup.bat b/tools/buildsteps/windows/BuildSetup.bat
index 0c4487c9e3..6e1aca3e86 100644
--- a/tools/buildsteps/windows/BuildSetup.bat
+++ b/tools/buildsteps/windows/BuildSetup.bat
@@ -266,39 +266,48 @@ set WORKSPACE=%base_dir%\kodi-build.%TARGET_PLATFORM%
:MAKE_APPX
set app_ext=msix
+ set app_path=%base_dir%\project\UWPBuildSetup
+ if not exist "%app_path%" mkdir %app_path%
call %base_dir%\project\Win32BuildSetup\extract_git_rev.bat > NUL
for /F %%a IN ('dir /B /S %WORKSPACE%\AppPackages ^| findstr /I /R "%APP_NAME%_.*_%TARGET_ARCHITECTURE%_%buildconfig%\.%app_ext%$"') DO (
- copy /Y %%a %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
- copy /Y %%~dpna.cer %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
- copy /Y %%~dpna.appxsym %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
- goto END
+ copy /Y %%a %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
+ copy /Y %%~dpna.cer %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
+ copy /Y %%~dpna.appxsym %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
+ goto END_APPX
)
rem Release builds don't have Release in it's name
for /F %%a IN ('dir /B /S %WORKSPACE%\AppPackages ^| findstr /I /R "%APP_NAME%_.*_%TARGET_ARCHITECTURE%\.%app_ext%$"') DO (
- copy /Y %%a %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
- copy /Y %%~dpna.cer %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
- copy /Y %%~dpna.appxsym %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
- goto END
+ copy /Y %%a %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
+ copy /Y %%~dpna.cer %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
+ copy /Y %%~dpna.appxsym %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
+ goto END_APPX
)
rem apxx file has win32 instead of x86 in it's name
if %TARGET_ARCHITECTURE%==x86 (
for /F %%a IN ('dir /B /S %WORKSPACE%\AppPackages ^| findstr /I /R "%APP_NAME%_.*_win32_%buildconfig%\.%app_ext%$"') DO (
- copy /Y %%a %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
- copy /Y %%~dpna.cer %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
- copy /Y %%~dpna.appxsym %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
- goto END
+ copy /Y %%a %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
+ copy /Y %%~dpna.cer %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
+ copy /Y %%~dpna.appxsym %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
+ goto END_APPX
)
rem Release builds don't have Release in it's name
for /F %%a IN ('dir /B /S %WORKSPACE%\AppPackages ^| findstr /I /R "%APP_NAME%_.*_win32\.%app_ext%$"') DO (
- copy /Y %%a %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
- copy /Y %%~dpna.cer %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
- copy /Y %%~dpna.appxsym %base_dir%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
- goto END
+ copy /Y %%a %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.%app_ext%
+ copy /Y %%~dpna.cer %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.cer
+ copy /Y %%~dpna.appxsym %app_path%\%APP_NAME%-%GIT_REV%-%BRANCH%-%TARGET_ARCHITECTURE%.appxsym
+ goto END_APPX
)
)
+:END_APPX
+ ECHO ------------------------------------------------------------
+ ECHO Done!
+ ECHO Setup is located at %app_path%
+ ECHO ------------------------------------------------------------
+ GOTO END
+
:DIE
ECHO ------------------------------------------------------------
ECHO !-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-
diff --git a/tools/buildsteps/windows/vswhere.bat b/tools/buildsteps/windows/vswhere.bat
index 999afb4466..f7b132bb37 100644
--- a/tools/buildsteps/windows/vswhere.bat
+++ b/tools/buildsteps/windows/vswhere.bat
@@ -38,7 +38,7 @@ IF "%arch%"=="x86" (
)
IF "%vcstore%"=="store" (
- SET sdkver=10.0.17763.0
+ SET sdkver=10.0.18362.0
SET toolsdir="win10-%toolsdir%"
)
diff --git a/tools/darwin/Support/Codesign-topshelf.command b/tools/darwin/Support/Codesign-topshelf.command
new file mode 100755
index 0000000000..8b9a3ffe83
--- /dev/null
+++ b/tools/darwin/Support/Codesign-topshelf.command
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -x
+
+LDID="$NATIVEPREFIX/bin/ldid"
+
+# Delete existing codesign and provisioning file
+rm -f "${CODESIGNING_FOLDER_PATH}/embedded.mobileprovision"
+rm -rf "${CODESIGNING_FOLDER_PATH}/_CodeSignature"
+
+# If user has not set a code_sign_identity we do a fake sign
+if [ -z "${CODE_SIGN_IDENTITY}" ]; then
+ # Do fake sign - needed for iOS >=5.1 and tvOS >=10.2 jailbroken devices
+ # See http://www.saurik.com/id/8
+ echo "Doing a fake sign of Top Shelf binary using ldid for jailbroken devices"
+ "${LDID}" -S "${CODESIGNING_FOLDER_PATH}/${EXECUTABLE_NAME}"
+fi
diff --git a/tools/darwin/Support/Codesign.command b/tools/darwin/Support/Codesign.command
index 44486e6956..e75410d4ef 100755
--- a/tools/darwin/Support/Codesign.command
+++ b/tools/darwin/Support/Codesign.command
@@ -2,10 +2,9 @@
set -x
-#this is the list of binaries we have to sign for being able to run un-jailbroken
+# This is the list of binaries we have to sign for being able to run un-jailbroken
LIST_BINARY_EXTENSIONS="dylib so app"
-GEN_ENTITLEMENTS="$NATIVEPREFIX/bin/gen_entitlements.py"
DARWIN_EMBEDDED_ENTITLEMENTS="$XBMC_DEPENDS/share/darwin_embedded_entitlements.xml"
LDID="$NATIVEPREFIX/bin/ldid"
@@ -13,26 +12,15 @@ if [ "${PLATFORM_NAME}" == "macosx" ]; then
MACOS=1
fi
-if [[ ! "$MACOS" && ! -f ${GEN_ENTITLEMENTS} ]]; then
- echo "error: $GEN_ENTITLEMENTS not found. Codesign won't work."
- exit -1
-fi
-
if [ "$MACOS" ]; then
CONTENTS_PATH="${CODESIGNING_FOLDER_PATH}/Contents"
else
CONTENTS_PATH="${CODESIGNING_FOLDER_PATH}"
fi
-if [ ! "$MACOS" ]; then
- # do fake sign - needed for iOS >=5.1 and tvOS >=10.2 jailbroken devices
- # see http://www.saurik.com/id/8
- "${LDID}" -S"${DARWIN_EMBEDDED_ENTITLEMENTS}" "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}/${EXECUTABLE_NAME}"
-fi
-
-# pull the CFBundleIdentifier out of the built xxx.app
+# Pull the CFBundleIdentifier out of the built xxx.app
BUNDLEID=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "${CONTENTS_PATH}/Info.plist")
-echo "CFBundleIdentifier is ${BUNDLEID}"
+echo "CFBundleIdentifier is '${BUNDLEID}'"
# Prefer the expanded name, if available.
CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
@@ -40,28 +28,21 @@ if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then
# Fall back to old behavior.
CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}"
fi
-echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}"
-
-if [ ! "$MACOS" ]; then
- ${GEN_ENTITLEMENTS} "${BUNDLEID}" "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}/${EXECUTABLE_NAME}.xcent"
- if [ -f "${CONTENTS_PATH}/embedded.mobileprovision" ]; then
- rm -f "${CONTENTS_PATH}/embedded.mobileprovision"
- fi
-fi
+echo "Code sign identity is '${CODE_SIGN_IDENTITY_FOR_ITEMS}'"
-# delete existing codesigning
-if [ -d "${CONTENTS_PATH}/_CodeSignature" ]; then
- rm -r "${CONTENTS_PATH}/_CodeSignature"
-fi
+# Delete existing codesign and provisioning file
+rm -f "${CONTENTS_PATH}/embedded.mobileprovision"
+rm -rf "${CONTENTS_PATH}/_CodeSignature"
-#if user has set a code_sign_identity different from iPhone Developer we do a real codesign (for deployment on non-jailbroken devices)
+# If user has set a code_sign_identity we do a real codesign (for deployment on non-jailbroken devices)
if ! [ -z "${CODE_SIGN_IDENTITY_FOR_ITEMS}" ]; then
if egrep -q --max-count=1 -e '^iPhone (Developer|Distribution): ' -e '^Apple (Development|Distribution): ' -e '^[[:xdigit:]]+$' -e '^Developer ID Application: ' <<<"${CODE_SIGN_IDENTITY_FOR_ITEMS}"; then
- echo "Doing a full bundle sign using genuine identity ${CODE_SIGN_IDENTITY_FOR_ITEMS}"
+ echo "Doing a full bundle sign using genuine identity '${CODE_SIGN_IDENTITY_FOR_ITEMS}'"
+
for binext in $LIST_BINARY_EXTENSIONS
do
- echo "Signing binary: $binext"
- # check if at least 1 file with the extension exists to sign, otherwise do nothing
+ echo "Signing binaries with '$binext' extension"
+ # Check if at least 1 file with the extension exists to sign, otherwise do nothing
FINDOUTPUT=$(find "${CONTENTS_PATH}" -iname "*.$binext" -type f)
if [ `echo $FINDOUTPUT | wc -l` != 0 ]; then
for singlefile in $FINDOUTPUT; do
@@ -80,7 +61,7 @@ if ! [ -z "${CODE_SIGN_IDENTITY_FOR_ITEMS}" ]; then
done
if [ "$MACOS" ]; then
- #sign and repackage python eggs for osx
+ # Sign and repackage python eggs for osx
EGGS=$(find "${CONTENTS_PATH}" -iname "*.egg" -type f)
echo "Signing Eggs"
for i in $EGGS; do
@@ -89,7 +70,7 @@ if ! [ -z "${CODE_SIGN_IDENTITY_FOR_ITEMS}" ]; then
unzip -q $i -d del
for binext in $LIST_BINARY_EXTENSIONS
do
- # check if at least 1 file with the extension exists to sign, otherwise do nothing
+ # Check if at least 1 file with the extension exists to sign, otherwise do nothing
FINDOUTPUT=$(find ./del/ -iname "*.$binext" -type f)
if [ `echo $FINDOUTPUT | wc -l` != 0 ]; then
for singlefile in $FINDOUTPUT; do
@@ -103,4 +84,18 @@ if ! [ -z "${CODE_SIGN_IDENTITY_FOR_ITEMS}" ]; then
done
fi
fi
+elif [ ! "$MACOS" ]; then
+ # Do fake sign - needed for iOS >=5.1 and tvOS >=10.2 jailbroken devices
+ # See http://www.saurik.com/id/8
+ echo "Doing a fake sign using ldid for jailbroken devices (main kodi binary and all Mach-O files)"
+
+ # Main 'kodi' binary
+ "${LDID}" -S"${DARWIN_EMBEDDED_ENTITLEMENTS}" "${CONTENTS_PATH}/${EXECUTABLE_NAME}"
+
+ # All Mach-O files (except TopShelf)
+ for f in $(find "${CONTENTS_PATH}/AppData" "${CONTENTS_PATH}/Frameworks" -type f); do
+ if [[ $(file ${f}) == *"Mach-O"* ]]; then
+ "${LDID}" -S "${f}"
+ fi
+ done
fi
diff --git a/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in b/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in
index a1d1121199..78cb87aada 100644
--- a/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in
+++ b/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in
@@ -109,7 +109,6 @@ cp -r $APP $DIRNAME/$PACKAGE/Applications/
find $DIRNAME/$PACKAGE/Applications/ -name '.svn' -exec rm -rf {} \;
find $DIRNAME/$PACKAGE/Applications/ -name '.git*' -exec rm -rf {} \;
find $DIRNAME/$PACKAGE/Applications/ -name '.DS_Store' -exec rm -rf {} \;
-find $DIRNAME/$PACKAGE/Applications/ -name '*.xcent' -exec rm -rf {} \;
echo Packaging $PACKAGE
# Tell tar, pax, etc. on Mac OS X 10.4+ not to archive
diff --git a/tools/depends/README.md b/tools/depends/README.md
index b4bc0587dd..2e5db17886 100644
--- a/tools/depends/README.md
+++ b/tools/depends/README.md
@@ -20,25 +20,25 @@ Paths below are examples. If you want to build Kodi, follow our **[build guides]
### All platforms
`./bootstrap`
### Darwin
-**macOS (x86_64)**
+**macOS (x86_64)**
`./configure --host=x86_64-apple-darwin`
-**iOS (arm64)**
+**iOS (arm64)**
`./configure --host=aarch64-apple-darwin`
-**tvOS**
+**tvOS**
`./configure --host=aarch64-apple-darwin --with-platform=tvos`
**NOTE:** You can target the same `--prefix=` path. Each setup will be done in an isolated directory. The last configure/make you do is the one used for Kodi/Xcode.
-
+
### Android
-**arm**
+**arm**
`./configure --with-tarballs=$HOME/android-tools/xbmc-tarballs --host=arm-linux-androideabi --with-sdk-path=$HOME/android-tools/android-sdk-linux --with-ndk-path=$HOME/android-tools/android-ndk-r20 --prefix=$HOME/android-tools/xbmc-depends`
-**aarch64**
+**aarch64**
`./configure --with-tarballs=$HOME/android-tools/xbmc-tarballs --host=aarch64-linux-android --with-sdk-path=$HOME/android-tools/android-sdk-linux --with-ndk-path=$HOME/android-tools/android-ndk-r20 --prefix=$HOME/android-tools/xbmc-depends`
-**x86**
+**x86**
`./configure --with-tarballs=$HOME/android-tools/xbmc-tarballs --host=i686-linux-android --with-sdk-path=$HOME/android-tools/android-sdk-linux --with-ndk-path=$HOME/android-tools/android-ndk-r20 --prefix=$HOME/android-tools/xbmc-depends`
**x86_64**
@@ -47,13 +47,10 @@ Paths below are examples. If you want to build Kodi, follow our **[build guides]
> **Note:** Android x86 and x86_64 are not maintained and are not 100% sure that everything works correctly!
### Linux
-**ARM (codesourcery/lenaro/etc)**
+**ARM (codesourcery/lenaro/etc)**
`./configure --with-toolchain=/opt/toolchains/my-example-toolchain/ --prefix=/opt/xbmc-deps --host=arm-linux-gnueabi`
-**Raspberry Pi**
-`./configure --with-platform=raspberry-pi --host=arm-linux-gnueabihf --prefix=/opt/xbmc-deps --with-tarballs=/opt/xbmc-tarballs --with-toolchain=/opt/rbp-dev/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf --with-firmware=/opt/rbp-dev/firmware --build=i686-linux`
-
-**Native**
+**Native**
`./configure --with-toolchain=/usr --prefix=/opt/xbmc-deps --host=x86_64-linux-gnu`
Cross compiling is a PITA.
diff --git a/tools/depends/configure.ac b/tools/depends/configure.ac
index 3ab992a34e..83389ee165 100644
--- a/tools/depends/configure.ac
+++ b/tools/depends/configure.ac
@@ -7,7 +7,7 @@ AC_CONFIG_FILES([target/config.site native/config.site.native Makefile.include t
AC_CANONICAL_HOST
m4_include([m4/xbmc_arch.m4])
-m4_include([m4/ax_cxx_compile_stdcxx_14.m4])
+m4_include([m4/ax_cxx_compile_stdcxx.m4])
# check for not same cpu value
AC_DEFUN([MC_CHECK_NOT_CPU],
@@ -232,11 +232,6 @@ AC_PATH_TOOL([CC],[$platform_cc],,$PATH_FOR_HOST)
AC_PATH_TOOL([CXX],[$platform_cxx],,$PATH_FOR_HOST)
AC_PROG_CPP
-AX_CXX_COMPILE_STDCXX_14([noext],[mandatory])
-c14_flags=$(echo "$CFLAGS" | sed 's/-O@<:@123@:>@//g;s/-g //g;s/ //g')
-cxx14_flags=$(echo "$CXXFLAGS" | sed 's/-O@<:@123@:>@//g;s/-g //g;s/ //g')
-
-
case $host in
*-*linux-android*)
deps_dir="$use_host-$use_ndk_api-$build_type"
@@ -262,7 +257,7 @@ case $host in
if test "x$use_cpu" = "xarm64-v8a"; then
platform_cflags+=" -march=armv8-a -mtune=cortex-a53"
fi
- meson_cpu="arch64"
+ meson_cpu="aarch64"
;;
i*86*-linux-android*|x86_64*-linux-android*)
if test "x$use_cpu" = "xauto"; then
@@ -397,6 +392,7 @@ case $host in
11.*);;
12.*);;
13.*);;
+ 14.*);;
*)
AC_MSG_ERROR(error in configure of --with-sdk=$use_sdk)
;;
@@ -431,30 +427,6 @@ case $use_platform in
fi
target_platform=$use_platform
;;
- raspberry-pi)
- target_platform=raspberry-pi
- use_cpu=arm1176jzf-s
- ffmpeg_options_default="--cpu=arm1176jzf-s"
- platform_cflags="-mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp"
- platform_cxxflags="-mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp"
- platform_ldflags=""
- ;;
- raspberry-pi2)
- target_platform=raspberry-pi
- use_cpu=cortex-a7
- ffmpeg_options_default="--cpu=cortex-a7"
- platform_cflags="-fPIC -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -mvectorize-with-neon-quad"
- platform_cxxflags="-fPIC -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -mvectorize-with-neon-quad"
- platform_ldflags="-lpthread"
- ;;
- raspberry-pi3)
- target_platform=raspberry-pi
- use_cpu=cortex-a53
- ffmpeg_options_default="--cpu=cortex-a53"
- platform_cflags="-fPIC -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mvectorize-with-neon-quad"
- platform_cxxflags="-fPIC -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mvectorize-with-neon-quad"
- platform_ldflags="-lpthread"
- ;;
tvos)
platform_cflags+=" -fembed-bitcode"
platform_cxxflags+=" -fembed-bitcode"
@@ -468,32 +440,6 @@ case $use_platform in
AC_MSG_ERROR(unsupported platform ($use_platform))
esac
-if test "$target_platform" = "raspberry-pi" ; then
- if test -d "${use_firmware}/opt/vc/include"; then
- :
- else
- AC_MSG_ERROR([Raspberry Pi firmware not found])
- fi
- use_arch="arm"
- use_hardcoded_tables="yes"
- ARCH="arm"
- cross_compiling="yes"
- use_host="arm-linux-gnueabihf"
- deps_dir="$use_platform-$build_type"
- platform_cflags+=" -pipe -mabi=aapcs-linux -Wno-psabi \
- -Wa,-mno-warn-deprecated -Wno-deprecated-declarations \
- -isystem${use_firmware}/opt/vc/include \
- -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \
- -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux"
- platform_cxxflags+=" -pipe -mabi=aapcs-linux -Wno-psabi \
- -Wa,-mno-warn-deprecated -Wno-deprecated-declarations \
- -isystem${use_firmware}/opt/vc/include \
- -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \
- -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux"
- platform_ldflags+=" -L${use_firmware}/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos \
- -lvchiq_arm"
-fi
-
XBMC_SETUP_ARCH_DEFINES()
@@ -611,8 +557,8 @@ if [ ! `mkdir -p $use_tarballs` ]; then
fi
# remove unwanted optimization flags
-tmp_cflags=$(echo $c14_flags $platform_cflags | sed 's/-O@<:@123@:>@//g;s/-g //g;s/ \{2,\}//g')
-tmp_cxxflags=$(echo $cxx14_flags $platform_cxxflags | sed 's/-O@<:@123@:>@//g;s/-g //g;s/ \{2,\}//g')
+tmp_cflags=$(echo $CFLAGS $platform_cflags | sed 's/-O@<:@123@:>@//g;s/-g //g;s/ \{2,\}//g')
+tmp_cxxflags=$(echo $CXXFLAGS $platform_cxxflags | sed 's/-O@<:@123@:>@//g;s/-g //g;s/ \{2,\}//g')
release_cflags="-DNDEBUG=1"
@@ -642,6 +588,12 @@ else
platform_cxxflags="$platform_cxxflags_release"
fi
+CXXFLAGS="$platform_cxxflags $platform_includes"
+CXX_CACHED="$CXX"
+AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])
+CXX="$CXX_CACHED"
+platform_cxxflags+=" -std=c++17"
+
if test "$ffmpeg_options" == "default"; then
ffmpeg_options="$ffmpeg_options_default"
fi
@@ -708,6 +660,8 @@ echo -e "build type:\t $build_type"
echo -e "toolchain:\t $use_toolchain"
echo -e "cpu:\t\t $use_cpu"
echo -e "host:\t\t $use_host"
+echo -e "CC:\t\t $CC"
+echo -e "CXX:\t\t $CXX"
echo -e "cflags:\t\t $platform_cflags"
echo -e "cxxflags:\t $platform_cxxflags"
echo -e "ldflags:\t $platform_ldflags"
diff --git a/tools/depends/m4/ax_cxx_compile_stdcxx.m4 b/tools/depends/m4/ax_cxx_compile_stdcxx.m4
new file mode 100644
index 0000000000..43087b2e68
--- /dev/null
+++ b/tools/depends/m4/ax_cxx_compile_stdcxx.m4
@@ -0,0 +1,951 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
+#
+# DESCRIPTION
+#
+# Check for baseline language coverage in the compiler for the specified
+# version of the C++ standard. If necessary, add switches to CXX and
+# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
+# or '14' (for the C++14 standard).
+#
+# The second argument, if specified, indicates whether you insist on an
+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+# -std=c++11). If neither is specified, you get whatever works, with
+# preference for an extended mode.
+#
+# The third argument, if specified 'mandatory' or if left unspecified,
+# indicates that baseline support for the specified C++ standard is
+# required and that the macro should error out if no mode with that
+# support is found. If specified 'optional', then configuration proceeds
+# regardless, after defining HAVE_CXX${VERSION} if and only if a
+# supporting mode is found.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+# Copyright (c) 2015 Paul Norman <penorman@mac.com>
+# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
+# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 11
+
+dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
+dnl (serial version number 13).
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
+ m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
+ [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
+ [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
+ [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
+ m4_if([$2], [], [],
+ [$2], [ext], [],
+ [$2], [noext], [],
+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
+ m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
+ [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
+ [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
+ [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
+ AC_LANG_PUSH([C++])dnl
+ ac_success=no
+
+ m4_if([$2], [noext], [], [dnl
+ if test x$ac_success = xno; then
+ for alternative in ${ax_cxx_compile_alternatives}; do
+ switch="-std=gnu++${alternative}"
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+ $cachevar,
+ [ac_save_CXX="$CXX"
+ CXX="$CXX $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXX="$ac_save_CXX"])
+ if eval test x\$$cachevar = xyes; then
+ CXX="$CXX $switch"
+ if test -n "$CXXCPP" ; then
+ CXXCPP="$CXXCPP $switch"
+ fi
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+
+ m4_if([$2], [ext], [], [dnl
+ if test x$ac_success = xno; then
+ dnl HP's aCC needs +std=c++11 according to:
+ dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
+ dnl Cray's crayCC needs "-h std=c++11"
+ for alternative in ${ax_cxx_compile_alternatives}; do
+ for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+ $cachevar,
+ [ac_save_CXX="$CXX"
+ CXX="$CXX $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXX="$ac_save_CXX"])
+ if eval test x\$$cachevar = xyes; then
+ CXX="$CXX $switch"
+ if test -n "$CXXCPP" ; then
+ CXXCPP="$CXXCPP $switch"
+ fi
+ ac_success=yes
+ break
+ fi
+ done
+ if test x$ac_success = xyes; then
+ break
+ fi
+ done
+ fi])
+ AC_LANG_POP([C++])
+ if test x$ax_cxx_compile_cxx$1_required = xtrue; then
+ if test x$ac_success = xno; then
+ AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
+ fi
+ fi
+ if test x$ac_success = xno; then
+ HAVE_CXX$1=0
+ AC_MSG_NOTICE([No compiler with C++$1 support was found])
+ else
+ HAVE_CXX$1=1
+ AC_DEFINE(HAVE_CXX$1,1,
+ [define if the compiler supports basic C++$1 syntax])
+ fi
+ AC_SUBST(HAVE_CXX$1)
+])
+
+
+dnl Test body for checking C++11 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+)
+
+
+dnl Test body for checking C++14 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+)
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
+)
+
+dnl Tests for new features in C++11
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+ namespace test_static_assert
+ {
+
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ }
+
+ namespace test_final_override
+ {
+
+ struct Base
+ {
+ virtual ~Base() {}
+ virtual void f() {}
+ };
+
+ struct Derived : public Base
+ {
+ virtual ~Derived() override {}
+ virtual void f() override {}
+ };
+
+ }
+
+ namespace test_double_right_angle_brackets
+ {
+
+ template < typename T >
+ struct check {};
+
+ typedef check<void> single_type;
+ typedef check<check<void>> double_type;
+ typedef check<check<check<void>>> triple_type;
+ typedef check<check<check<check<void>>>> quadruple_type;
+
+ }
+
+ namespace test_decltype
+ {
+
+ int
+ f()
+ {
+ int a = 1;
+ decltype(a) b = 2;
+ return a + b;
+ }
+
+ }
+
+ namespace test_type_deduction
+ {
+
+ template < typename T1, typename T2 >
+ struct is_same
+ {
+ static const bool value = false;
+ };
+
+ template < typename T >
+ struct is_same<T, T>
+ {
+ static const bool value = true;
+ };
+
+ template < typename T1, typename T2 >
+ auto
+ add(T1 a1, T2 a2) -> decltype(a1 + a2)
+ {
+ return a1 + a2;
+ }
+
+ int
+ test(const int c, volatile int v)
+ {
+ static_assert(is_same<int, decltype(0)>::value == true, "");
+ static_assert(is_same<int, decltype(c)>::value == false, "");
+ static_assert(is_same<int, decltype(v)>::value == false, "");
+ auto ac = c;
+ auto av = v;
+ auto sumi = ac + av + 'x';
+ auto sumf = ac + av + 1.0;
+ static_assert(is_same<int, decltype(ac)>::value == true, "");
+ static_assert(is_same<int, decltype(av)>::value == true, "");
+ static_assert(is_same<int, decltype(sumi)>::value == true, "");
+ static_assert(is_same<int, decltype(sumf)>::value == false, "");
+ static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+ return (sumf > 0.0) ? sumi : add(c, v);
+ }
+
+ }
+
+ namespace test_noexcept
+ {
+
+ int f() { return 0; }
+ int g() noexcept { return 0; }
+
+ static_assert(noexcept(f()) == false, "");
+ static_assert(noexcept(g()) == true, "");
+
+ }
+
+ namespace test_constexpr
+ {
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+ {
+ return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+ }
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c(const CharT *const s) noexcept
+ {
+ return strlen_c_r(s, 0UL);
+ }
+
+ static_assert(strlen_c("") == 0UL, "");
+ static_assert(strlen_c("1") == 1UL, "");
+ static_assert(strlen_c("example") == 7UL, "");
+ static_assert(strlen_c("another\0example") == 7UL, "");
+
+ }
+
+ namespace test_rvalue_references
+ {
+
+ template < int N >
+ struct answer
+ {
+ static constexpr int value = N;
+ };
+
+ answer<1> f(int&) { return answer<1>(); }
+ answer<2> f(const int&) { return answer<2>(); }
+ answer<3> f(int&&) { return answer<3>(); }
+
+ void
+ test()
+ {
+ int i = 0;
+ const int c = 0;
+ static_assert(decltype(f(i))::value == 1, "");
+ static_assert(decltype(f(c))::value == 2, "");
+ static_assert(decltype(f(0))::value == 3, "");
+ }
+
+ }
+
+ namespace test_uniform_initialization
+ {
+
+ struct test
+ {
+ static const int zero {};
+ static const int one {1};
+ };
+
+ static_assert(test::zero == 0, "");
+ static_assert(test::one == 1, "");
+
+ }
+
+ namespace test_lambdas
+ {
+
+ void
+ test1()
+ {
+ auto lambda1 = [](){};
+ auto lambda2 = lambda1;
+ lambda1();
+ lambda2();
+ }
+
+ int
+ test2()
+ {
+ auto a = [](int i, int j){ return i + j; }(1, 2);
+ auto b = []() -> int { return '0'; }();
+ auto c = [=](){ return a + b; }();
+ auto d = [&](){ return c; }();
+ auto e = [a, &b](int x) mutable {
+ const auto identity = [](int y){ return y; };
+ for (auto i = 0; i < a; ++i)
+ a += b--;
+ return x + identity(a + b);
+ }(0);
+ return a + b + c + d + e;
+ }
+
+ int
+ test3()
+ {
+ const auto nullary = [](){ return 0; };
+ const auto unary = [](int x){ return x; };
+ using nullary_t = decltype(nullary);
+ using unary_t = decltype(unary);
+ const auto higher1st = [](nullary_t f){ return f(); };
+ const auto higher2nd = [unary](nullary_t f1){
+ return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+ };
+ return higher1st(nullary) + higher2nd(nullary)(unary);
+ }
+
+ }
+
+ namespace test_variadic_templates
+ {
+
+ template <int...>
+ struct sum;
+
+ template <int N0, int... N1toN>
+ struct sum<N0, N1toN...>
+ {
+ static constexpr auto value = N0 + sum<N1toN...>::value;
+ };
+
+ template <>
+ struct sum<>
+ {
+ static constexpr auto value = 0;
+ };
+
+ static_assert(sum<>::value == 0, "");
+ static_assert(sum<1>::value == 1, "");
+ static_assert(sum<23>::value == 23, "");
+ static_assert(sum<1, 2>::value == 3, "");
+ static_assert(sum<5, 5, 11>::value == 21, "");
+ static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+ }
+
+ // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+ // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+ // because of this.
+ namespace test_template_alias_sfinae
+ {
+
+ struct foo {};
+
+ template<typename T>
+ using member = typename T::member_type;
+
+ template<typename T>
+ void func(...) {}
+
+ template<typename T>
+ void func(member<T>*) {}
+
+ void test();
+
+ void test() { func<foo>(0); }
+
+ }
+
+} // namespace cxx11
+
+#endif // __cplusplus >= 201103L
+
+]])
+
+
+dnl Tests for new features in C++14
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+ namespace test_polymorphic_lambdas
+ {
+
+ int
+ test()
+ {
+ const auto lambda = [](auto&&... args){
+ const auto istiny = [](auto x){
+ return (sizeof(x) == 1UL) ? 1 : 0;
+ };
+ const int aretiny[] = { istiny(args)... };
+ return aretiny[0];
+ };
+ return lambda(1, 1L, 1.0f, '1');
+ }
+
+ }
+
+ namespace test_binary_literals
+ {
+
+ constexpr auto ivii = 0b0000000000101010;
+ static_assert(ivii == 42, "wrong value");
+
+ }
+
+ namespace test_generalized_constexpr
+ {
+
+ template < typename CharT >
+ constexpr unsigned long
+ strlen_c(const CharT *const s) noexcept
+ {
+ auto length = 0UL;
+ for (auto p = s; *p; ++p)
+ ++length;
+ return length;
+ }
+
+ static_assert(strlen_c("") == 0UL, "");
+ static_assert(strlen_c("x") == 1UL, "");
+ static_assert(strlen_c("test") == 4UL, "");
+ static_assert(strlen_c("another\0test") == 7UL, "");
+
+ }
+
+ namespace test_lambda_init_capture
+ {
+
+ int
+ test()
+ {
+ auto x = 0;
+ const auto lambda1 = [a = x](int b){ return a + b; };
+ const auto lambda2 = [a = lambda1(x)](){ return a; };
+ return lambda2();
+ }
+
+ }
+
+ namespace test_digit_separators
+ {
+
+ constexpr auto ten_million = 100'000'000;
+ static_assert(ten_million == 100000000, "");
+
+ }
+
+ namespace test_return_type_deduction
+ {
+
+ auto f(int& x) { return x; }
+ decltype(auto) g(int& x) { return x; }
+
+ template < typename T1, typename T2 >
+ struct is_same
+ {
+ static constexpr auto value = false;
+ };
+
+ template < typename T >
+ struct is_same<T, T>
+ {
+ static constexpr auto value = true;
+ };
+
+ int
+ test()
+ {
+ auto x = 0;
+ static_assert(is_same<int, decltype(f(x))>::value, "");
+ static_assert(is_same<int&, decltype(g(x))>::value, "");
+ return x;
+ }
+
+ }
+
+} // namespace cxx14
+
+#endif // __cplusplus >= 201402L
+
+]])
+
+
+dnl Tests for new features in C++17
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
+
+// If the compiler admits that it is not ready for C++17, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201703L
+
+#error "This is not a C++17 compiler"
+
+#else
+
+#include <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+ namespace test_constexpr_lambdas
+ {
+
+ constexpr int foo = [](){return 42;}();
+
+ }
+
+ namespace test::nested_namespace::definitions
+ {
+
+ }
+
+ namespace test_fold_expression
+ {
+
+ template<typename... Args>
+ int multiply(Args... args)
+ {
+ return (args * ... * 1);
+ }
+
+ template<typename... Args>
+ bool all(Args... args)
+ {
+ return (args && ...);
+ }
+
+ }
+
+ namespace test_extended_static_assert
+ {
+
+ static_assert (true);
+
+ }
+
+ namespace test_auto_brace_init_list
+ {
+
+ auto foo = {5};
+ auto bar {5};
+
+ static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
+ static_assert(std::is_same<int, decltype(bar)>::value);
+ }
+
+ namespace test_typename_in_template_template_parameter
+ {
+
+ template<template<typename> typename X> struct D;
+
+ }
+
+ namespace test_fallthrough_nodiscard_maybe_unused_attributes
+ {
+
+ int f1()
+ {
+ return 42;
+ }
+
+ [[nodiscard]] int f2()
+ {
+ [[maybe_unused]] auto unused = f1();
+
+ switch (f1())
+ {
+ case 17:
+ f1();
+ [[fallthrough]];
+ case 42:
+ f1();
+ }
+ return f1();
+ }
+
+ }
+
+ namespace test_extended_aggregate_initialization
+ {
+
+ struct base1
+ {
+ int b1, b2 = 42;
+ };
+
+ struct base2
+ {
+ base2() {
+ b3 = 42;
+ }
+ int b3;
+ };
+
+ struct derived : base1, base2
+ {
+ int d;
+ };
+
+ derived d1 {{1, 2}, {}, 4}; // full initialization
+ derived d2 {{}, {}, 4}; // value-initialized bases
+
+ }
+
+ namespace test_general_range_based_for_loop
+ {
+
+ struct iter
+ {
+ int i;
+
+ int& operator* ()
+ {
+ return i;
+ }
+
+ const int& operator* () const
+ {
+ return i;
+ }
+
+ iter& operator++()
+ {
+ ++i;
+ return *this;
+ }
+ };
+
+ struct sentinel
+ {
+ int i;
+ };
+
+ bool operator== (const iter& i, const sentinel& s)
+ {
+ return i.i == s.i;
+ }
+
+ bool operator!= (const iter& i, const sentinel& s)
+ {
+ return !(i == s);
+ }
+
+ struct range
+ {
+ iter begin() const
+ {
+ return {0};
+ }
+
+ sentinel end() const
+ {
+ return {5};
+ }
+ };
+
+ void f()
+ {
+ range r {};
+
+ for (auto i : r)
+ {
+ [[maybe_unused]] auto v = i;
+ }
+ }
+
+ }
+
+ namespace test_lambda_capture_asterisk_this_by_value
+ {
+
+ struct t
+ {
+ int i;
+ int foo()
+ {
+ return [*this]()
+ {
+ return i;
+ }();
+ }
+ };
+
+ }
+
+ namespace test_enum_class_construction
+ {
+
+ enum class byte : unsigned char
+ {};
+
+ byte foo {42};
+
+ }
+
+ namespace test_constexpr_if
+ {
+
+ template <bool cond>
+ int f ()
+ {
+ if constexpr(cond)
+ {
+ return 13;
+ }
+ else
+ {
+ return 42;
+ }
+ }
+
+ }
+
+ namespace test_selection_statement_with_initializer
+ {
+
+ int f()
+ {
+ return 13;
+ }
+
+ int f2()
+ {
+ if (auto i = f(); i > 0)
+ {
+ return 3;
+ }
+
+ switch (auto i = f(); i + 4)
+ {
+ case 17:
+ return 2;
+
+ default:
+ return 1;
+ }
+ }
+
+ }
+
+ namespace test_template_argument_deduction_for_class_templates
+ {
+
+ template <typename T1, typename T2>
+ struct pair
+ {
+ pair (T1 p1, T2 p2)
+ : m1 {p1},
+ m2 {p2}
+ {}
+
+ T1 m1;
+ T2 m2;
+ };
+
+ void f()
+ {
+ [[maybe_unused]] auto p = pair{13, 42u};
+ }
+
+ }
+
+ namespace test_non_type_auto_template_parameters
+ {
+
+ template <auto n>
+ struct B
+ {};
+
+ B<5> b1;
+ B<'a'> b2;
+
+ }
+
+ namespace test_structured_bindings
+ {
+
+ int arr[2] = { 1, 2 };
+ std::pair<int, int> pr = { 1, 2 };
+
+ auto f1() -> int(&)[2]
+ {
+ return arr;
+ }
+
+ auto f2() -> std::pair<int, int>&
+ {
+ return pr;
+ }
+
+ struct S
+ {
+ int x1 : 2;
+ volatile double y1;
+ };
+
+ S f3()
+ {
+ return {};
+ }
+
+ auto [ x1, y1 ] = f1();
+ auto& [ xr1, yr1 ] = f1();
+ auto [ x2, y2 ] = f2();
+ auto& [ xr2, yr2 ] = f2();
+ const auto [ x3, y3 ] = f3();
+
+ }
+
+ namespace test_exception_spec_type_system
+ {
+
+ struct Good {};
+ struct Bad {};
+
+ void g1() noexcept;
+ void g2();
+
+ template<typename T>
+ Bad
+ f(T*, T*);
+
+ template<typename T1, typename T2>
+ Good
+ f(T1*, T2*);
+
+ static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+ }
+
+ namespace test_inline_variables
+ {
+
+ template<class T> void f(T)
+ {}
+
+ template<class T> inline T g(T)
+ {
+ return T{};
+ }
+
+ template<> inline void f<>(int)
+ {}
+
+ template<> int g<>(int)
+ {
+ return 5;
+ }
+
+ }
+
+} // namespace cxx17
+
+#endif // __cplusplus < 201703L
+
+]])
diff --git a/tools/depends/m4/ax_cxx_compile_stdcxx_14.m4 b/tools/depends/m4/ax_cxx_compile_stdcxx_14.m4
deleted file mode 100644
index 3a46bf7e61..0000000000
--- a/tools/depends/m4/ax_cxx_compile_stdcxx_14.m4
+++ /dev/null
@@ -1,146 +0,0 @@
-# ============================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_14.html
-# ============================================================================
-#
-# SYNOPSIS
-#
-# AX_CXX_COMPILE_STDCXX_14([ext|noext],[mandatory|optional])
-#
-# DESCRIPTION
-#
-# Check for baseline language coverage in the compiler for the C++14
-# standard; if necessary, add switches to CXXFLAGS to enable support.
-#
-# The first argument, if specified, indicates whether you insist on an
-# extended mode (e.g. -std=gnu++14) or a strict conformance mode (e.g.
-# -std=c++14). If neither is specified, you get whatever works, with
-# preference for an extended mode.
-#
-# The second argument, if specified 'mandatory' or if left unspecified,
-# indicates that baseline C++14 support is required and that the macro
-# should error out if no mode with that support is found. If specified
-# 'optional', then configuration proceeds regardless, after defining
-# HAVE_CXX14 if and only if a supporting mode is found.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
-# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
-# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
-# Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
-#
-# Copying and distribution of this file, with or without modification, are
-# permitted in any medium without royalty provided the copyright notice
-# and this notice are preserved. This file is offered as-is, without any
-# warranty.
-
-#serial 4
-
-m4_define([_AX_CXX_COMPILE_STDCXX_14_testbody], [[
- template <typename T>
- struct check
- {
- static_assert(sizeof(int) <= sizeof(T), "not big enough");
- };
-
- struct Base {
- virtual void f() {}
- };
- struct Child : public Base {
- virtual void f() {}
- };
-
- typedef check<check<bool>> right_angle_brackets;
-
- int a;
- decltype(a) b;
-
- typedef check<int> check_type;
- check_type c;
- check_type&& cr = static_cast<check_type&&>(c);
-
- auto d = a;
- auto l = [](){};
-]])
-
-AC_DEFUN([AX_CXX_COMPILE_STDCXX_14], [dnl
- m4_if([$1], [], [],
- [$1], [ext], [],
- [$1], [noext], [],
- [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_14])])dnl
- m4_if([$2], [], [ax_cxx_compile_cxx14_required=true],
- [$2], [mandatory], [ax_cxx_compile_cxx14_required=true],
- [$2], [optional], [ax_cxx_compile_cxx14_required=false],
- [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_14])])
- AC_LANG_PUSH([C++])dnl
- ac_success=no
- AC_CACHE_CHECK(whether $CXX supports C++14 features by default,
- ax_cv_cxx_compile_cxx14,
- [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_14_testbody])],
- [ax_cv_cxx_compile_cxx14=yes],
- [ax_cv_cxx_compile_cxx14=no])])
- if test x$ax_cv_cxx_compile_cxx14 = xyes; then
- ac_success=yes
- fi
-
- m4_if([$1], [noext], [], [dnl
- if test x$ac_success = xno; then
- for switch in -std=gnu++14 -std=gnu++0x; do
- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx14_$switch])
- AC_CACHE_CHECK(whether $CXX supports C++14 features with $switch,
- $cachevar,
- [ac_save_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS="$CXXFLAGS $switch"
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_14_testbody])],
- [eval $cachevar=yes],
- [eval $cachevar=no])
- CXXFLAGS="$ac_save_CXXFLAGS"])
- if eval test x\$$cachevar = xyes; then
- CXXFLAGS="$CXXFLAGS $switch"
- CXX14_SWITCH="$switch"
- AC_SUBST(CXX14_SWITCH)
- ac_success=yes
- break
- fi
- done
- fi])
-
- m4_if([$1], [ext], [], [dnl
- if test x$ac_success = xno; then
- for switch in -std=c++14 -std=c++0x; do
- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx14_$switch])
- AC_CACHE_CHECK(whether $CXX supports C++14 features with $switch,
- $cachevar,
- [ac_save_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS="$CXXFLAGS $switch"
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_14_testbody])],
- [eval $cachevar=yes],
- [eval $cachevar=no])
- CXXFLAGS="$ac_save_CXXFLAGS"])
- if eval test x\$$cachevar = xyes; then
- CXXFLAGS="$CXXFLAGS $switch"
- CXX14_SWITCH="$switch"
- AC_SUBST(CXX14_SWITCH)
- ac_success=yes
- break
- fi
- done
- fi])
- AC_LANG_POP([C++])
- if test x$ax_cxx_compile_cxx14_required = xtrue; then
- if test x$ac_success = xno; then
- AC_MSG_ERROR([*** A compiler with support for C++14 language features is required.])
- fi
- else
- if test x$ac_success = xno; then
- HAVE_CXX14=0
- AC_MSG_NOTICE([No compiler with C++14 support was found])
- else
- HAVE_CXX14=1
- AC_DEFINE(HAVE_CXX14,1,
- [define if the compiler supports basic C++14 syntax])
- fi
-
- AC_SUBST(HAVE_CXX14)
- fi
-])
diff --git a/tools/depends/m4/xbmc_arch.m4 b/tools/depends/m4/xbmc_arch.m4
index b4beef8f77..83e42552c7 100644
--- a/tools/depends/m4/xbmc_arch.m4
+++ b/tools/depends/m4/xbmc_arch.m4
@@ -74,7 +74,4 @@ if test "$target_platform" = "target_android" ; then
AC_SUBST(ARCH_DEFINES, "-DTARGET_POSIX -DTARGET_LINUX -DTARGET_ANDROID")
fi
-if test "$target_platform" = "target_raspberry_pi" ; then
- AC_SUBST(ARCH_DEFINES, "-DTARGET_POSIX -DTARGET_LINUX -D_ARMEL -DTARGET_RASPBERRY_PI")
-fi
])
diff --git a/tools/depends/native/Makefile b/tools/depends/native/Makefile
index 4e012d9b22..e5aff1f9df 100644
--- a/tools/depends/native/Makefile
+++ b/tools/depends/native/Makefile
@@ -15,7 +15,7 @@ NATIVE= m4 gettext heimdal autoconf automake \
ifeq ($(OS),darwin_embedded)
- NATIVE += dpkg xz tar gen_entitlements ldid
+ NATIVE += dpkg xz tar ldid
endif
ifeq ($(TARGET_PLATFORM),wayland)
@@ -23,6 +23,10 @@ ifeq ($(TARGET_PLATFORM),wayland)
EXPAT = expat
endif
+ifeq ($(TARGET_PLATFORM),gbm)
+ NATIVE += MarkupSafe Mako
+endif
+
.PHONY: $(NATIVE) native
all: native
@@ -38,7 +42,7 @@ libtool: automake
libjpeg-turbo: cmake yasm
libpng: zlib
meson: python3 setuptools
-ninja: python3
+ninja: meson
swig: pcre
distutilscross: python3
tar: xz automake
@@ -47,6 +51,12 @@ setuptools: python3
wayland-scanner: expat
waylandpp-scanner: cmake
+# python installs are not thread safe when using easy_install method.
+# MarkupSafe doesn't really depend on ninja but we need to make the
+# build sequential
+MarkupSafe: ninja
+Mako: MarkupSafe
+
#liblzo2 has stale packaged automake files that cause borked host/build detection
liblzo2: automake
JsonSchemaBuilder: automake
diff --git a/tools/depends/native/Mako/Makefile b/tools/depends/native/Mako/Makefile
new file mode 100644
index 0000000000..6bb675f5ae
--- /dev/null
+++ b/tools/depends/native/Mako/Makefile
@@ -0,0 +1,29 @@
+include ../../Makefile.include
+PREFIX=$(NATIVEPREFIX)
+PLATFORM=$(NATIVEPLATFORM)
+DEPS= ../../Makefile.include Makefile
+
+# lib name, version
+LIBNAME=Mako
+VERSION=1.1.3
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+
+all: .installed-$(PLATFORM)
+
+$(TARBALLS_LOCATION)/$(ARCHIVE):
+ cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
+ cd $(TARBALLS_LOCATION); chmod +x $(ARCHIVE)
+
+$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
+ -rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+.installed-$(PLATFORM): $(PLATFORM)
+ cd $(PLATFORM); $(PREFIX)/bin/python3 setup.py install --prefix=$(PREFIX)
+ touch $@
+
+clean:
+ rm -f .installed-$(PLATFORM)
+
+distclean::
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/tools/depends/native/MarkupSafe/Makefile b/tools/depends/native/MarkupSafe/Makefile
new file mode 100644
index 0000000000..ef7b8cec1c
--- /dev/null
+++ b/tools/depends/native/MarkupSafe/Makefile
@@ -0,0 +1,29 @@
+include ../../Makefile.include
+PREFIX=$(NATIVEPREFIX)
+PLATFORM=$(NATIVEPLATFORM)
+DEPS= ../../Makefile.include Makefile
+
+# lib name, version
+LIBNAME=MarkupSafe
+VERSION=1.1.1
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+
+all: .installed-$(PLATFORM)
+
+$(TARBALLS_LOCATION)/$(ARCHIVE):
+ cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
+ cd $(TARBALLS_LOCATION); chmod +x $(ARCHIVE)
+
+$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
+ -rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+.installed-$(PLATFORM): $(PLATFORM)
+ cd $(PLATFORM); $(PREFIX)/bin/python3 setup.py install --prefix=$(PREFIX)
+ touch $@
+
+clean:
+ rm -f .installed-$(PLATFORM)
+
+distclean::
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/tools/depends/native/gen_entitlements/Makefile b/tools/depends/native/gen_entitlements/Makefile
deleted file mode 100644
index a16b4549f6..0000000000
--- a/tools/depends/native/gen_entitlements/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include ../../Makefile.include
-
-GEBIN=$(NATIVEPREFIX)/bin/gen_entitlements.py
-
-all: $(GEBIN)
-
-$(GEBIN):
- mkdir -p $(NATIVEPREFIX)/bin
- cp gen_entitlements.py $(GEBIN)
- chmod 755 $(GEBIN)
-
-clean:
-distclean::
- rm -f $(GEBIN)
diff --git a/tools/depends/native/gen_entitlements/gen_entitlements.py b/tools/depends/native/gen_entitlements/gen_entitlements.py
deleted file mode 100755
index d8ae6af3ee..0000000000
--- a/tools/depends/native/gen_entitlements/gen_entitlements.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import struct
-
-if len(sys.argv) != 3:
- print "Usage: %s appname dest_file.xcent" % sys.argv[0]
- sys.exit(-1)
-
-APPNAME = sys.argv[1]
-DEST = sys.argv[2]
-
-if not DEST.endswith('.xml') and not DEST.endswith('.xcent'):
- print "Dest must be .xml (for ldid) or .xcent (for codesign)"
- sys.exit(-1)
-
-entitlements = """
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>application-identifier</key>
- <string>%s</string>
- <key>get-task-allow</key>
- <true/>
-</dict>
-</plist>
-""" % APPNAME
-
-f = open(DEST,'w')
-if DEST.endswith('.xcent'):
- f.write("\xfa\xde\x71\x71")
- f.write(struct.pack('>L', len(entitlements) + 8))
-f.write(entitlements)
-f.close()
-
diff --git a/tools/depends/native/meson/Makefile b/tools/depends/native/meson/Makefile
index 832f1a9f43..842201c184 100644
--- a/tools/depends/native/meson/Makefile
+++ b/tools/depends/native/meson/Makefile
@@ -4,7 +4,7 @@ DEPS=../../Makefile.include Makefile
# lib name, version
LIBNAME=meson
-VERSION=0.51.0
+VERSION=0.55.1
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.gz
diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile
index 74734b3d83..6f6d32f2d6 100644
--- a/tools/depends/target/Makefile
+++ b/tools/depends/target/Makefile
@@ -12,7 +12,7 @@ DEPENDS = \
libxml2 rapidjson libmicrohttpd mariadb libffi \
python3 libshairplay libfmt libspdlog \
libplist libcec libbluray tinyxml \
- taglib libusb libnfs meson-cross-file \
+ taglib libusb libnfs \
pythonmodule-pil pythonmodule-pycryptodome pythonmodule-setuptools \
libxslt ffmpeg crossguid libudfread \
libdvdread libdvdnav libdvdcss p8-platform flatbuffers dav1d
@@ -61,17 +61,19 @@ endif
WAYLANDPP_DEPS=
ALSA_LIB=
ifeq ($(OS),linux)
- DEPENDS += dbus libuuid
- #not for raspberry pi
- ifneq ($(TARGET_PLATFORM),raspberry-pi)
- DEPENDS += linux-system-libs
- WAYLANDPP_DEPS += linux-system-libs
- endif
- DEPENDS += alsa-lib
+ DEPENDS += dbus libuuid alsa-lib
ALSA_LIB = alsa-lib
LIBUUID = libuuid
- ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),raspberry-pi gbm))
- DEPENDS += libxkbcommon libinput libudev libevdev mtdev
+
+ ifeq ($(TARGET_PLATFORM),gbm)
+ DEPENDS += libxkbcommon libinput libudev libevdev mtdev libdrm mesa
+ ifeq ($(CPU),x86_64)
+ DEPENDS += libva
+ LIBVA = libva
+ endif
+ else
+ DEPENDS += linux-system-libs
+ WAYLANDPP_DEPS += linux-system-libs
endif
endif
@@ -104,7 +106,7 @@ pythonmodule-pycryptodome: $(PYMODULE_DEPS) python3 pythonmodule-setuptools
pythonmodule-pil: bzip2 $(PYMODULE_DEPS) $(ZLIB) libjpeg-turbo libpng freetype2 python3 pythonmodule-setuptools
pythonmodule-setuptools: $(PYMODULE_DEPS) python3
libxslt: libgcrypt libxml2
-ffmpeg: $(ICONV) $(ZLIB) bzip2 gnutls dav1d
+ffmpeg: $(ICONV) $(ZLIB) bzip2 gnutls dav1d $(LIBVA)
libcec: p8-platform
crossguid: $(LIBUUID)
libdvdnav: libdvdread
@@ -119,6 +121,9 @@ taglib: $(ZLIB)
dav1d: meson-cross-file
fribidi: meson-cross-file
libspdlog: libfmt
+libdrm: meson-cross-file
+mesa: libdrm meson-cross-file
+libva: libdrm
.installed-$(PLATFORM): $(DEPENDS)
touch $@
@@ -186,7 +191,7 @@ linux-system-libs: linux-system-libs-egl
[ -f $(PREFIX)/lib/pkgconfig/xkbcommon.pc ] || ln -sf /usr/lib/$(HOST)/pkgconfig/xkbcommon.pc $(PREFIX)/lib/pkgconfig/xkbcommon.pc
[ -f $(PREFIX)/lib/pkgconfig/libva.pc ] || ln -sf /usr/lib/$(HOST)/pkgconfig/libva.pc $(PREFIX)/lib/pkgconfig/libva.pc
-meson-cross-file:
+$(PREFIX)/share/cross-file.meson:
PREFIX="$(PREFIX)" \
NATIVEPREFIX="$(NATIVEPREFIX)" \
CC="$(CC)" \
@@ -199,5 +204,7 @@ meson-cross-file:
CFLAGS="$(CFLAGS)" \
CXXFLAGS="$(CXXFLAGS)" \
LDFLAGS="$(LDFLAGS)" \
- ./meson-cross-setup.sh
+ ./meson-cross-setup.sh $@
+.PHONY: meson-cross-file
+meson-cross-file: $(PREFIX)/share/cross-file.meson
diff --git a/tools/depends/target/Toolchain.cmake.in b/tools/depends/target/Toolchain.cmake.in
index 7b5ea6ab0e..8786f52f7e 100644
--- a/tools/depends/target/Toolchain.cmake.in
+++ b/tools/depends/target/Toolchain.cmake.in
@@ -10,14 +10,7 @@ set(PLATFORM "@target_platform@")
if(OS STREQUAL linux)
set(CMAKE_SYSTEM_NAME Linux)
set(CORE_SYSTEM_NAME linux)
- if(PLATFORM STREQUAL raspberry-pi)
- set(CORE_PLATFORM_NAME rbpi)
- # wrapping libdvd fails with gold on rbpi
- # todo: revisit after toolchain bump
- set(ENABLE_LDGOLD OFF CACHE BOOL "Disabling Gnu Gold Linker" FORCE)
- elseif(NOT "@target_platform@" STREQUAL "")
- set(CORE_PLATFORM_NAME @target_platform@)
- endif()
+ set(CORE_PLATFORM_NAME @target_platform@)
if(NOT "@app_rendersystem@" STREQUAL "")
set(X11_RENDER_SYSTEM @app_rendersystem@ CACHE STRING "Render system to use with X11: \"gl\" or \"gles\"")
set(WAYLAND_RENDER_SYSTEM @app_rendersystem@ CACHE STRING "Render system to use with Wayland: \"gl\" or \"gles\"")
@@ -100,13 +93,6 @@ if(NOT "@use_sdk_path@" STREQUAL "")
list(APPEND CMAKE_FIND_ROOT_PATH @use_sdk_path@ @use_sdk_path@/usr)
endif()
-# add RBPI's firmware directories
-if(CORE_PLATFORM_NAME STREQUAL rbpi)
- list(APPEND CMAKE_FIND_ROOT_PATH @use_firmware@/opt/vc)
- list(APPEND CMAKE_LIBRARY_PATH @use_firmware@/opt/vc/lib)
- list(APPEND CMAKE_INCLUDE_PATH @use_firmware@/opt/vc/include)
-endif()
-
# add Android directories and tools
if(CORE_SYSTEM_NAME STREQUAL android)
set(NDKROOT @use_ndk_path@)
diff --git a/tools/depends/target/Toolchain_binaddons.cmake.in b/tools/depends/target/Toolchain_binaddons.cmake.in
index 30059d1c6d..27a6dbd3aa 100644
--- a/tools/depends/target/Toolchain_binaddons.cmake.in
+++ b/tools/depends/target/Toolchain_binaddons.cmake.in
@@ -10,15 +10,7 @@ set(CMAKE_FIND_ROOT_PATH @CMAKE_FIND_ROOT_PATH@)
if(OS STREQUAL linux)
set(CMAKE_SYSTEM_NAME Linux)
set(CORE_SYSTEM_NAME linux)
- if(PLATFORM STREQUAL raspberry-pi)
- set(CORE_PLATFORM_NAME rbpi)
- set(ENABLE_LDGOLD OFF CACHE BOOL "Disabling Gnu Gold Linker" FORCE)
- if(NOT APP_RENDER_SYSTEM)
- set(APP_RENDER_SYSTEM gles)
- endif()
- elseif(NOT "@target_platform@" STREQUAL "")
- set(CORE_PLATFORM_NAME @target_platform@)
- endif()
+ set(CORE_PLATFORM_NAME @target_platform@)
if(NOT APP_RENDER_SYSTEM)
set(APP_RENDER_SYSTEM gl)
endif()
@@ -73,13 +65,6 @@ if(NOT "@use_toolchain@" STREQUAL "")
list(APPEND CMAKE_FIND_ROOT_PATH @use_toolchain@/sysroot/usr)
endif()
-# add RBPI's firmware directories
-if(CORE_PLATFORM_NAME STREQUAL rbpi)
- list(APPEND CMAKE_FIND_ROOT_PATH @use_firmware@/opt/vc)
- list(APPEND CMAKE_LIBRARY_PATH @CMAKE_FIND_ROOT_PATH@/lib:@use_firmware@/opt/vc/lib)
- list(APPEND CMAKE_INCLUDE_PATH @CMAKE_FIND_ROOT_PATH@/include:@use_firmware@/opt/vc/include)
-endif()
-
# add Android directories and tools
if(CORE_SYSTEM_NAME STREQUAL android)
set(NDKROOT @use_ndk_path@)
diff --git a/tools/depends/target/dav1d/Makefile b/tools/depends/target/dav1d/Makefile
index be5f2fa835..6201255cfd 100644
--- a/tools/depends/target/dav1d/Makefile
+++ b/tools/depends/target/dav1d/Makefile
@@ -51,7 +51,7 @@ export CC CXX CFLAGS CXXFLAGS
endif
export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig
-LIBDYLIB=$(PLATFORM)/lib/lib$(LIBNAME).a
+LIBDYLIB=$(PLATFORM)/build/src/lib$(LIBNAME).a
all: .installed-$(PLATFORM)
diff --git a/tools/depends/target/ffmpeg/CMakeLists.txt b/tools/depends/target/ffmpeg/CMakeLists.txt
index 3ebd65cf13..e358775911 100644
--- a/tools/depends/target/ffmpeg/CMakeLists.txt
+++ b/tools/depends/target/ffmpeg/CMakeLists.txt
@@ -39,20 +39,16 @@ if(CMAKE_BUILD_TYPE STREQUAL Release)
endif()
if(CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd)
- if(CORE_PLATFORM_NAME STREQUAL rbpi)
- list(APPEND ffmpeg_conf --cpu=${CPU} --disable-vaapi --disable-vdpau)
+ list(APPEND ffmpeg_conf --enable-pic)
+ if(ENABLE_VAAPI)
+ list(APPEND ffmpeg_conf --enable-vaapi)
else()
- list(APPEND ffmpeg_conf --enable-pic)
- if(ENABLE_VAAPI)
- list(APPEND ffmpeg_conf --enable-vaapi)
- else()
- list(APPEND ffmpeg_conf --disable-vaapi)
- endif()
- if(ENABLE_VDPAU)
- list(APPEND ffmpeg_conf --enable-vdpau)
- else()
- list(APPEND ffmpeg_conf --disable-vdpau)
- endif()
+ list(APPEND ffmpeg_conf --disable-vaapi)
+ endif()
+ if(ENABLE_VDPAU)
+ list(APPEND ffmpeg_conf --enable-vdpau)
+ else()
+ list(APPEND ffmpeg_conf --disable-vdpau)
endif()
elseif(CORE_SYSTEM_NAME STREQUAL android)
if(CPU MATCHES arm64)
@@ -75,7 +71,7 @@ elseif(CORE_SYSTEM_NAME STREQUAL osx)
--disable-securetransport)
endif()
-if(CPU MATCHES arm OR CORE_PLATFORM_NAME STREQUAL rbpi)
+if(CPU MATCHES arm)
list(APPEND ffmpeg_conf --enable-pic --disable-armv5te --disable-armv6t2)
elseif(CPU MATCHES mips)
list(APPEND ffmpeg_conf --disable-mips32r2 --disable-mipsdsp --disable-mipsdspr2)
@@ -99,6 +95,16 @@ endif()
message(STATUS "FFMPEG_CONF: ${ffmpeg_conf}")
+set(MAKE_COMMAND $(MAKE))
+if(CMAKE_GENERATOR STREQUAL Ninja)
+ set(MAKE_COMMAND make)
+ include(ProcessorCount)
+ ProcessorCount(N)
+ if(NOT N EQUAL 0)
+ set(MAKE_COMMAND make -j${N})
+ endif()
+endif()
+
include(ExternalProject)
externalproject_add(ffmpeg
SOURCE_DIR ${CMAKE_SOURCE_DIR}
@@ -124,7 +130,8 @@ externalproject_add(ffmpeg
--enable-protocol=http
--enable-encoder=png
--enable-encoder=mjpeg
- ${ffmpeg_conf})
+ ${ffmpeg_conf}
+ BUILD_COMMAND ${MAKE_COMMAND})
install(CODE "Message(Done)")
diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION
index cf780452fc..ae224efe31 100644
--- a/tools/depends/target/ffmpeg/FFMPEG-VERSION
+++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION
@@ -1,4 +1,4 @@
LIBNAME=ffmpeg
BASE_URL=https://github.com/xbmc/FFmpeg
-VERSION=4.3.1-Matrix-Alpha1-1
+VERSION=4.3.1-Matrix-Alpha1-2
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
diff --git a/tools/depends/target/libandroidjni/Makefile b/tools/depends/target/libandroidjni/Makefile
index 13f62b5493..b664e7243f 100644
--- a/tools/depends/target/libandroidjni/Makefile
+++ b/tools/depends/target/libandroidjni/Makefile
@@ -3,7 +3,7 @@ DEPS= ../../Makefile.include Makefile
# lib name, version
LIBNAME=libandroidjni
-VERSION=ee5cc102101d9cb04ab4dbfd7a65db1c52345faf
+VERSION=e00d271b5dbfa050fb9876df73b617cfe33326b1
SOURCE=archive
ARCHIVE=$(VERSION).tar.gz
GIT_BASE_URL=https://github.com/xbmc
diff --git a/tools/depends/target/libdrm/Makefile b/tools/depends/target/libdrm/Makefile
new file mode 100644
index 0000000000..7aa8d4120c
--- /dev/null
+++ b/tools/depends/target/libdrm/Makefile
@@ -0,0 +1,76 @@
+include ../../Makefile.include
+DEPS=../../Makefile.include Makefile
+
+LIBNAME=libdrm
+VERSION=2.4.102
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.xz
+
+MESON_BUILD_TYPE=release
+
+ifeq ($(DEBUG_BUILD), yes)
+ MESON_BUILD_TYPE=debug
+endif
+
+# configuration settings
+CONFIGURE = $(NATIVEPREFIX)/bin/python3 $(NATIVEPREFIX)/bin/meson \
+ --prefix=$(PREFIX) \
+ --libdir=lib \
+ --buildtype=$(MESON_BUILD_TYPE) \
+ -Dlibkms=false \
+ -Dnouveau=false \
+ -Domap=false \
+ -Dexynos=false \
+ -Dtegra=false \
+ -Dintel=false \
+ -Dradeon=false \
+ -Damdgpu=false \
+ -Dvmwgfx=false \
+ -Dvc4=false \
+ -Dfreedreno=false \
+ -Detnaviv=false \
+ -Dcairo-tests=false \
+ -Dman-pages=false \
+ -Dvalgrind=false \
+ -Dfreedreno-kgsl=false \
+ -Dinstall-test-programs=false \
+ -Dudev=false
+
+ifeq ($(CROSS_COMPILING), yes)
+CONFIGURE += --cross-file $(PREFIX)/share/cross-file.meson
+export CC=$(CC_FOR_BUILD)
+export CXX=$(CXX_FOR_BUILD)
+export CFLAGS=$(CFLAGS_FOR_BUILD)
+export CXXFLAGS=$(CXXFLAGS_FOR_BUILD)
+else
+export CC CXX CFLAGS CXXFLAGS
+endif
+export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig
+
+LIBDYLIB=$(PLATFORM)/build/$(LIBNAME).so
+
+all: .installed-$(PLATFORM)
+
+download: $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+$(TARBALLS_LOCATION)/$(ARCHIVE):
+ cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
+
+$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
+ rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ cd $(PLATFORM); rm -rf build; mkdir -p build
+ cd $(PLATFORM); $(CONFIGURE) . build
+
+$(LIBDYLIB): $(PLATFORM)
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v
+
+.installed-$(PLATFORM): $(LIBDYLIB)
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v install
+ touch $@
+
+clean:
+ $(MAKE) -C $(PLATFORM) clean
+ rm -f .installed-$(PLATFORM)
+
+distclean:
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/tools/depends/target/libfmt/Makefile b/tools/depends/target/libfmt/Makefile
index 5bc7b7bc40..b10eb2ef99 100644
--- a/tools/depends/target/libfmt/Makefile
+++ b/tools/depends/target/libfmt/Makefile
@@ -7,7 +7,7 @@ VERSION=6.1.2
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.gz
-CMAKE_OPTIONS=-DCMAKE_CXX_STANDARD=14 -DCMAKE_CXX_EXTENSIONS:BOOL=OFF -DFMT_DOC=OFF -DFMT_INSTALL=ON -DFMT_TEST=OFF
+CMAKE_OPTIONS=-DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_EXTENSIONS:BOOL=OFF -DFMT_DOC=OFF -DFMT_INSTALL=ON -DFMT_TEST=OFF
ifeq ($(CROSS_COMPILING), yes)
DEPS += ../../Makefile.include
diff --git a/tools/depends/target/libinput/Makefile b/tools/depends/target/libinput/Makefile
index ccf98657ff..3811495ea1 100644
--- a/tools/depends/target/libinput/Makefile
+++ b/tools/depends/target/libinput/Makefile
@@ -27,7 +27,7 @@ export CC CXX CFLAGS CXXFLAGS
endif
export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig
-LIBDYLIB=$(PLATFORM)/build/libinput.a
+LIBDYLIB=$(PLATFORM)/build/libinput.so
all: .installed-$(PLATFORM)
diff --git a/tools/depends/target/libspdlog/Makefile b/tools/depends/target/libspdlog/Makefile
index 9bbecbf461..aecb4dde6a 100644
--- a/tools/depends/target/libspdlog/Makefile
+++ b/tools/depends/target/libspdlog/Makefile
@@ -17,7 +17,7 @@ CMAKE_OPTIONS= \
ifeq ($(CROSS_COMPILING), yes)
DEPS += ../../Makefile.include
else
- CXXFLAGS += -std=c++14
+ CXXFLAGS += -std=c++17
ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
ifeq ($(PLATFORM),)
diff --git a/tools/depends/target/libva/Makefile b/tools/depends/target/libva/Makefile
new file mode 100644
index 0000000000..dd1f586297
--- /dev/null
+++ b/tools/depends/target/libva/Makefile
@@ -0,0 +1,64 @@
+include ../../Makefile.include
+DEPS=../../Makefile.include Makefile
+
+LIBNAME=libva
+VERSION=2.8.0
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.bz2
+
+MESON_BUILD_TYPE=release
+
+ifeq ($(DEBUG_BUILD), yes)
+ MESON_BUILD_TYPE=debug
+endif
+
+# configuration settings
+CONFIGURE = $(NATIVEPREFIX)/bin/python3 $(NATIVEPREFIX)/bin/meson \
+ --prefix=$(PREFIX) \
+ --libdir=lib \
+ --buildtype=$(MESON_BUILD_TYPE) \
+ -Ddisable_drm=false \
+ -Denable_docs=false \
+ -Denable_va_messaging=true \
+ -Dwith_x11=no \
+ -Dwith_glx=no \
+ -Dwith_wayland=no
+
+ifeq ($(CROSS_COMPILING), yes)
+CONFIGURE += --cross-file $(PREFIX)/share/cross-file.meson
+export CC=$(CC_FOR_BUILD)
+export CXX=$(CXX_FOR_BUILD)
+export CFLAGS=$(CFLAGS_FOR_BUILD)
+export CXXFLAGS=$(CXXFLAGS_FOR_BUILD)
+else
+export CC CXX CFLAGS CXXFLAGS
+endif
+export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig
+
+LIBDYLIB=$(PLATFORM)/build/$(LIBNAME).so
+
+all: .installed-$(PLATFORM)
+
+download: $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+$(TARBALLS_LOCATION)/$(ARCHIVE):
+ cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
+
+$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
+ rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ cd $(PLATFORM); rm -rf build; mkdir -p build
+ cd $(PLATFORM); $(CONFIGURE) . build
+
+$(LIBDYLIB): $(PLATFORM)
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v
+
+.installed-$(PLATFORM): $(LIBDYLIB)
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v install
+ touch $@
+
+clean:
+ $(MAKE) -C $(PLATFORM) clean
+ rm -f .installed-$(PLATFORM)
+
+distclean:
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/tools/depends/target/mesa/Makefile b/tools/depends/target/mesa/Makefile
new file mode 100644
index 0000000000..c9d3b72b81
--- /dev/null
+++ b/tools/depends/target/mesa/Makefile
@@ -0,0 +1,93 @@
+include ../../Makefile.include
+DEPS=../../Makefile.include Makefile
+
+LIBNAME=mesa
+VERSION=20.1.7
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.xz
+
+MESON_BUILD_TYPE=release
+
+ifeq ($(DEBUG_BUILD), yes)
+ MESON_BUILD_TYPE=debug
+endif
+
+ifeq ($(CPU), x86_64)
+ MESA_GALLIUM_DRIVERS=iris
+else ifeq ($(CPU), arm)
+ MESA_GALLIUM_DRIVERS=kmsro,vc4
+endif
+
+# configuration settings
+CONFIGURE = $(NATIVEPREFIX)/bin/python3 $(NATIVEPREFIX)/bin/meson \
+ --prefix=$(PREFIX) \
+ --libdir=lib \
+ --buildtype=$(MESON_BUILD_TYPE) \
+ -Ddri-drivers= \
+ -Dgallium-drivers="$(MESA_GALLIUM_DRIVERS)" \
+ -Dgallium-extra-hud=false \
+ -Dgallium-xvmc=false \
+ -Dgallium-omx=disabled \
+ -Dgallium-nine=false \
+ -Dgallium-opencl=disabled \
+ -Dvulkan-drivers= \
+ -Dshader-cache=true \
+ -Dshared-glapi=true \
+ -Dopengl=true \
+ -Dgbm=true \
+ -Degl=true \
+ -Dvalgrind=false \
+ -Dlibunwind=false \
+ -Dlmsensors=false \
+ -Dbuild-tests=false \
+ -Dselinux=false \
+ -Dosmesa=none \
+ -Dplatforms="drm" \
+ -Ddri3=false \
+ -Dglx=disabled \
+ -Dglvnd=false \
+ -Dllvm=false \
+ -Dgallium-vdpau=false \
+ -Dgallium-va=false \
+ -Dgallium-xa=false \
+ -Dgles1=false \
+ -Dgles2=true
+
+ifeq ($(CROSS_COMPILING), yes)
+CONFIGURE += --cross-file $(PREFIX)/share/cross-file.meson
+export CC=$(CC_FOR_BUILD)
+export CXX=$(CXX_FOR_BUILD)
+export CFLAGS=$(CFLAGS_FOR_BUILD)
+export CXXFLAGS=$(CXXFLAGS_FOR_BUILD)
+else
+export CC CXX CFLAGS CXXFLAGS
+endif
+export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig
+
+LIBDYLIB=$(PLATFORM)/build/src/egl/libEGL.so
+
+all: .installed-$(PLATFORM)
+
+download: $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+$(TARBALLS_LOCATION)/$(ARCHIVE):
+ cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
+
+$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
+ rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ cd $(PLATFORM); rm -rf build; mkdir -p build
+ cd $(PLATFORM); $(CONFIGURE) . build
+
+$(LIBDYLIB): $(PLATFORM)
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v
+
+.installed-$(PLATFORM): $(LIBDYLIB)
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v install
+ touch $@
+
+clean:
+ $(MAKE) -C $(PLATFORM) clean
+ rm -f .installed-$(PLATFORM)
+
+distclean:
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/tools/depends/target/meson-cross-setup.sh b/tools/depends/target/meson-cross-setup.sh
index dad98d24ae..9b5546200f 100755
--- a/tools/depends/target/meson-cross-setup.sh
+++ b/tools/depends/target/meson-cross-setup.sh
@@ -1,9 +1,9 @@
#!/bin/sh
-cat > $PREFIX/share/cross-file.meson << EOF
+cat > $1 << EOF
[binaries]
-$($NATIVEPREFIX/bin/python3 -c "print('c = \'{}\''.format('$CC'.split()[-1]))")
-$($NATIVEPREFIX/bin/python3 -c "print('cpp = \'{}\''.format('$CXX'.split()[-1]))")
+$($NATIVEPREFIX/bin/python3 -c "print('c = {}'.format('$CC'.split()))")
+$($NATIVEPREFIX/bin/python3 -c "print('cpp = {}'.format('$CXX'.split()))")
ar = '$AR'
strip = '$STRIP'
pkgconfig = '$NATIVEPREFIX/bin/pkg-config'
@@ -15,9 +15,9 @@ cpu = '$CPU'
endian = 'little'
[properties]
-$($NATIVEPREFIX/bin/python3 -c "print('c_args = {}'.format([x for x in '$CFLAGS'.split()]))")
+$($NATIVEPREFIX/bin/python3 -c "print('c_args = {}'.format([x for x in '$CFLAGS'.split() if x not in ['-g', '-gdwarf-2']]))")
$($NATIVEPREFIX/bin/python3 -c "print('c_link_args = {}'.format([x for x in '$LDFLAGS'.split()]))")
-$($NATIVEPREFIX/bin/python3 -c "print('cpp_args = {}'.format([x for x in '$CXXFLAGS'.split()]))")
+$($NATIVEPREFIX/bin/python3 -c "print('cpp_args = {}'.format([x for x in '$CXXFLAGS'.split() if x not in ['-g', '-gdwarf-2']]))")
$($NATIVEPREFIX/bin/python3 -c "print('cpp_link_args = {}'.format([x for x in '$LDFLAGS'.split()]))")
[paths]
diff --git a/tools/depends/target/nettle/02-conftest_exit.patch b/tools/depends/target/nettle/02-conftest_exit.patch
new file mode 100644
index 0000000000..bdc6c0400c
--- /dev/null
+++ b/tools/depends/target/nettle/02-conftest_exit.patch
@@ -0,0 +1,21 @@
+--- a/aclocal.m4
++++ b/aclocal.m4
+@@ -369,7 +369,7 @@
+ int
+ main ()
+ {
+- exit(0);
++ return 0;
+ }
+ EOF
+ gmp_compile="$1 conftest.c"
+@@ -410,7 +410,7 @@
+ int
+ main ()
+ {
+- exit (0);
++ return 0;
+ }
+ EOF
+ for i in .exe ,ff8 ""; do
+
diff --git a/tools/depends/target/nettle/Makefile b/tools/depends/target/nettle/Makefile
index f184912e42..dbc0cc65c0 100644
--- a/tools/depends/target/nettle/Makefile
+++ b/tools/depends/target/nettle/Makefile
@@ -1,5 +1,5 @@
include ../../Makefile.include
-DEPS= ../../Makefile.include Makefile 01-disable_testsuite.patch
+DEPS= ../../Makefile.include Makefile 01-disable_testsuite.patch 02-conftest_exit.patch
# lib name, version
LIBNAME=nettle
@@ -22,6 +22,8 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); patch -p1 -i ../01-disable_testsuite.patch
+ cd $(PLATFORM); patch -p1 -i ../02-conftest_exit.patch
+ cd $(PLATFORM); $(AUTORECONF)
cd $(PLATFORM); $(CONFIGURE) CCPIC=" "
$(LIBDYLIB): $(PLATFORM)
diff --git a/tools/depends/target/p8-platform/0001-fix-c++17-support.patch b/tools/depends/target/p8-platform/0001-fix-c++17-support.patch
new file mode 100644
index 0000000000..25fbe483fe
--- /dev/null
+++ b/tools/depends/target/p8-platform/0001-fix-c++17-support.patch
@@ -0,0 +1,22 @@
+diff --git a/src/util/StringUtils.cpp b/src/util/StringUtils.cpp
+index 510e2d5..3d25ba7 100644
+--- a/src/util/StringUtils.cpp
++++ b/src/util/StringUtils.cpp
+@@ -453,7 +453,7 @@ static int isspace_c(char c)
+
+ std::string& StringUtils::TrimLeft(std::string &str)
+ {
+- str.erase(str.begin(), ::find_if(str.begin(), str.end(), ::not1(::ptr_fun(isspace_c))));
++ str.erase(str.begin(), ::find_if(str.begin(), str.end(), [](char s) { return isspace_c(s) == 0; }));
+ return str;
+ }
+
+@@ -466,7 +466,7 @@ std::string& StringUtils::TrimLeft(std::string &str, const char* const chars)
+
+ std::string& StringUtils::TrimRight(std::string &str)
+ {
+- str.erase(::find_if(str.rbegin(), str.rend(), ::not1(::ptr_fun(isspace_c))).base(), str.end());
++ str.erase(::find_if(str.rbegin(), str.rend(), [](char s) { return isspace_c(s) == 0; }).base(), str.end());
+ return str;
+ }
+
diff --git a/tools/depends/target/p8-platform/Makefile b/tools/depends/target/p8-platform/Makefile
index 257f7e0561..e473262862 100644
--- a/tools/depends/target/p8-platform/Makefile
+++ b/tools/depends/target/p8-platform/Makefile
@@ -1,5 +1,5 @@
include ../../Makefile.include
-DEPS= ../../Makefile.include Makefile
+DEPS= ../../Makefile.include Makefile 0001-fix-c++17-support.patch
# lib name, version
LIBNAME=p8-platform
@@ -17,6 +17,7 @@ $(TARBALLS_LOCATION)/$(ARCHIVE):
$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
rm -rf $(PLATFORM); mkdir -p $(PLATFORM)/build
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ cd $(PLATFORM); patch -p1 -i ../0001-fix-c++17-support.patch
cd $(PLATFORM)/build; $(CMAKE) -DBUILD_SHARED_LIBS=0 -DCMAKE_INSTALL_LIBDIR=$(PREFIX)/lib ..
$(LIBDYLIB): $(PLATFORM)
@@ -31,4 +32,3 @@ clean:
distclean::
rm -rf $(PLATFORM) .installed-$(PLATFORM)
-
diff --git a/tools/depends/xbmc-addons.include b/tools/depends/xbmc-addons.include
index 35399f0e2f..79d7c069b4 100644
--- a/tools/depends/xbmc-addons.include
+++ b/tools/depends/xbmc-addons.include
@@ -6,11 +6,6 @@ export PKG_CONFIG_LIBDIR = $(ADDON_DEPS_DIR)/lib/pkgconfig
ifeq ($(CROSS_COMPILING),yes)
DEPS = $(TOOLCHAIN_FILE) $(abs_top_srcdir)/target/config-binaddons.site $(abs_top_srcdir)/target/Toolchain_binaddons.cmake $(CONFIG_SUB) $(CONFIG_GUESS)
TOOLCHAIN = -DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN_FILE)
- ifeq ($(OS),linux)
- ifneq ($(TARGET_PLATFORM),raspberry-pi)
- DEPS += linux-system-libs
- endif
- endif
endif
ifeq ($(PLATFORM),)
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index 39f6fcd21b..7cdae43440 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -451,16 +451,9 @@ bool CApplication::Create(const CAppParamParser &params)
#else
buildType = "Unknown";
#endif
- std::string specialVersion;
- //! @todo - move to CPlatformXXX
-#if defined(TARGET_RASPBERRY_PI)
- specialVersion = " (version for Raspberry Pi)";
-//#elif defined(some_ID) // uncomment for special version/fork
-// specialVersion = " (version for XXXX)";
-#endif
- CLog::Log(LOGINFO, "Using %s %s x%d build%s", buildType.c_str(), CSysInfo::GetAppName().c_str(),
- g_sysinfo.GetXbmcBitness(), specialVersion.c_str());
+ CLog::Log(LOGINFO, "Using %s %s x%d", buildType.c_str(), CSysInfo::GetAppName().c_str(),
+ g_sysinfo.GetXbmcBitness());
CLog::Log(
LOGINFO, "%s compiled %s by %s for %s %s %d-bit %s (%s)", CSysInfo::GetAppName().c_str(),
CSysInfo::GetBuildDate(), g_sysinfo.GetUsedCompilerNameAndVer().c_str(),
@@ -1637,7 +1630,10 @@ bool CApplication::OnAction(const CAction &action)
// playing or ACTION_PLAYER_PLAY if we are seeking (FF/RW) or not playing.
if (action.GetID() == ACTION_PLAYER_PLAYPAUSE)
{
- if (m_appPlayer.IsPlaying() && m_appPlayer.GetPlaySpeed() == 1)
+ CGUIWindowSlideShow* pSlideShow = CServiceBroker::GetGUI()->
+ GetWindowManager().GetWindow<CGUIWindowSlideShow>(WINDOW_SLIDESHOW);
+ if ((m_appPlayer.IsPlaying() && m_appPlayer.GetPlaySpeed() == 1) ||
+ (pSlideShow && pSlideShow->InSlideShow() && !pSlideShow->IsPaused()))
return OnAction(CAction(ACTION_PAUSE));
else
return OnAction(CAction(ACTION_PLAYER_PLAY));
@@ -1671,6 +1667,12 @@ bool CApplication::OnAction(const CAction &action)
// Display HDR : toggle HDR on/off
if (action.GetID() == ACTION_HDR_TOGGLE)
{
+ // Only enables manual HDR toggle if no video is playing or auto HDR switch is disabled
+ if (m_appPlayer.IsPlayingVideo() &&
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CServiceBroker::GetWinSystem()->SETTING_WINSYSTEM_IS_HDR_DISPLAY))
+ return true;
+
HDR_STATUS hdrStatus = CServiceBroker::GetWinSystem()->ToggleHDR();
if (hdrStatus == HDR_STATUS::HDR_OFF)
@@ -2444,7 +2446,8 @@ void CApplication::FrameMove(bool processEvents, bool processGUI)
if (processGUI && m_renderGUI)
{
m_skipGuiRender = false;
-#if defined(TARGET_RASPBERRY_PI)
+
+ /*! @todo look into the possibility to use this for GBM
int fps = 0;
// This code reduces rendering fps of the GUI layer when playing videos in fullscreen mode
@@ -2456,7 +2459,7 @@ void CApplication::FrameMove(bool processEvents, bool processGUI)
unsigned int frameTime = now - m_lastRenderTime;
if (fps > 0 && frameTime * fps < 1000)
m_skipGuiRender = true;
-#endif
+ */
if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiSmartRedraw && m_guiRefreshTimer.IsTimePast())
{
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
index aef925d6f9..1d0a20422c 100644
--- a/xbmc/GUIInfoManager.cpp
+++ b/xbmc/GUIInfoManager.cpp
@@ -469,6 +469,22 @@ const infomap integer_bools[] = {{ "isequal", INTEGER_IS_EQUAL },
/// video.
/// <p>
/// }
+/// \table_row3{ <b>`Player.offset(number).Title`</b>,
+/// \anchor Player_Offset_Title
+/// _string_,
+/// @return The title of audio or video which has an offset `number` with respect to the currently playing item.
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Title `Player.offset(number).Title`\endlink
+/// <p>
+/// }
+/// \table_row3{ <b>`Player.position(number).Title`</b>,
+/// \anchor Player_Position_Title
+/// _string_,
+/// @return The title of the audio or video which has an offset `number` with respect to the start of the playlist.
+/// <p>><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Position_Title `Player.position(number).Title`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`Player.Muted`</b>,
/// \anchor Player_Muted
/// _boolean_,
@@ -553,6 +569,22 @@ const infomap integer_bools[] = {{ "isequal", INTEGER_IS_EQUAL },
/// @return The full path of the currently playing song or movie
/// <p>
/// }
+/// \table_row3{ <b>`Player.offset(number).Folderpath`</b>,
+/// \anchor Player_Offset_Folderpath
+/// _string_,
+/// @return The full path of the audio or video file which has an offset `number` with respect to the currently playing item.
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Folderpath `Player.offset(number).Folderpath`\endlink
+/// <p>
+/// }
+/// \table_row3{ <b>`Player.position(number).Folderpath`</b>,
+/// \anchor Player_Position_Folderpath
+/// _string_,
+/// @return The full path of the audio or video file which has an offset `number` with respect to the start of the playlist.
+/// <p>><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Position_Folderpath `Player.position(number).Folderpath`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`Player.FilenameAndPath`</b>,
/// \anchor Player_FilenameAndPath
/// _string_,
@@ -560,6 +592,22 @@ const infomap integer_bools[] = {{ "isequal", INTEGER_IS_EQUAL },
/// playing song or movie
/// <p>
/// }
+/// \table_row3{ <b>`Player.offset(number).FilenameAndPath`</b>,
+/// \anchor Player_Offset_FilenameAndPath
+/// _string_,
+/// @return The full path with filename of audio or video file which has an offset `number` with respect to the currently playing item.
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Offset_FilenameAndPath `Player.offset(number).FilenameAndPath`\endlink
+/// <p>
+/// }
+/// \table_row3{ <b>`Player.position(number).FilenameAndPath`</b>,
+/// \anchor Player_Position_FilenameAndPath
+/// _string_,
+/// @return The full path with filename of the audio or video file which has an offset `number` with respect to the start of the playlist.
+/// <p>><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Position_FilenameAndPath `Player.position(number).FilenameAndPath`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`Player.Filename`</b>,
/// \anchor Player_Filename
/// _string_,
@@ -568,6 +616,22 @@ const infomap integer_bools[] = {{ "isequal", INTEGER_IS_EQUAL },
/// @skinning_v13 **[New Infolabel]** \link Player_Filename `Player.Filename`\endlink
/// <p>
/// }
+/// \table_row3{ <b>`Player.offset(number).Filename`</b>,
+/// \anchor Player_Offset_Filename
+/// _string_,
+/// @return The filename of audio or video file which has an offset `number` with respect to the currently playing item.
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Filename `Player.offset(number).Filename`\endlink
+/// <p>
+/// }
+/// \table_row3{ <b>`Player.position(number).Filename`</b>,
+/// \anchor Player_Position_Filename
+/// _string_,
+/// @return The filename of the audio or video file which has an offset `number` with respect to the start of the playlist.
+/// <p>><hr>
+/// @skinning_v19 **[New Infolabel]** \link Player_Position_Filename `Player.position(number).Filename`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`Player.IsInternetStream`</b>,
/// \anchor Player_IsInternetStream
/// _boolean_,
@@ -1164,14 +1228,6 @@ const infomap weather[] = {{ "isfetched", WEATHER_IS_FETCHED },
/// @return **True** if Kodi is running on a linux/unix based computer.
/// <p>
/// }
-/// \table_row3{ <b>`System.Platform.Linux.RaspberryPi`</b>,
-/// \anchor System_PlatformLinuxRaspberryPi
-/// _boolean_,
-/// @return **True** if Kodi is running on a Raspberry Pi.
-/// <p><hr>
-/// @skinning_v13 **[New Boolean Condition]** \link System_PlatformLinuxRaspberryPi
-/// `System.Platform.Linux.RaspberryPi`\endlink <p>
-/// }
/// \table_row3{ <b>`System.Platform.Windows`</b>,
/// \anchor System_PlatformWindows
/// _boolean_,
@@ -2601,6 +2657,22 @@ const infomap musicpartymode[] = {{ "enabled", MUSICPM_ENABLED },
/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_BPM `MusicPlayer.BPM`\endlink
/// <p>
/// }
+/// \table_row3{ <b>`MusicPlayer.IsMultiDisc`</b>,
+/// \anchor MusicPlayer_IsMultiDisc
+/// _boolean_,
+/// @return Returns **true** if the album currently playing has more than one disc.
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_IsMultiDisc `MusicPlayer.IsMultiDisc`\endlink
+/// <p>
+/// }
+/// \table_row3{ <b>`MusicPlayer.TotalDiscs`</b>,
+/// \anchor MusicPlayer_TotalDiscs
+/// _string_,
+/// @return The number of discs associated with the currently playing album.
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_TotalDiscs `MusicPlayer.TotalDiscs`\endlink
+/// <p>
+/// }
/// \table_end
///
/// -----------------------------------------------------------------------------
@@ -2644,7 +2716,9 @@ const infomap musicplayer[] = {{ "title", MUSICPLAYER_TITLE },
{ "property", MUSICPLAYER_PROPERTY },
{ "releasedate", MUSICPLAYER_RELEASEDATE },
{ "originaldate", MUSICPLAYER_ORIGINALDATE },
- { "bpm", MUSICPLAYER_BPM }
+ { "bpm", MUSICPLAYER_BPM },
+ { "ismultidisc", MUSICPLAYER_ISMULTIDISC },
+ { "totaldiscs", MUSICPLAYER_TOTALDISCS }
};
/// \page modules__infolabels_boolean_conditions
@@ -4373,6 +4447,14 @@ const infomap container_str[] = {{ "property", CONTAINER_PROPERTY },
/// replaces `ListItem.Property(Addon.UpdateAvail)`.
/// <p>
/// }
+/// \table_row3{ <b>`ListItem.IsAutoUpdateable`</b>,
+/// \anchor ListItem_IsAutoUpdateable
+/// _boolean_,
+/// @return **True** if this add-on can be updated automatically.
+/// <p><hr>
+/// @skinning_v19 **[New Boolean Condition]** \link ListItem_IsAutoUpdateable `ListItem.IsAutoUpdateable`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`ListItem.Property(Addon.IsFromOfficialRepo)`</b>,
/// \anchor ListItem_Property_AddonIsFromOfficialRepo
/// _boolean_,
@@ -4389,6 +4471,14 @@ const infomap container_str[] = {{ "property", CONTAINER_PROPERTY },
/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsBinary `ListItem.Property(Addon.IsBinary)`\endlink
/// <p>
/// }
+/// \table_row3{ <b>`ListItem.Property(Addon.IsUpdate)`</b>,
+/// \anchor ListItem_Property_AddonIsUpdate
+/// _boolean_,
+/// @return **True** if this add-on is a valid update of an installed outdated add-on.
+/// <p><hr>
+/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsUpdate `ListItem.Property(Addon.IsUpdate)`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`ListItem.Label`</b>,
/// \anchor ListItem_Label
/// _string_,
@@ -6062,11 +6152,35 @@ const infomap container_str[] = {{ "property", CONTAINER_PROPERTY },
/// \anchor ListItem_AddonBroken
/// _string_,
/// @return A message when the addon is marked as broken in the repo.
+/// @deprecated but still available\, use \ref ListItem_AddonLifecycleDesc "ListItem.AddonLifecycleDesc"
+/// instead
/// <p><hr>
/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonBroken `ListItem.AddonBroken`\endlink
/// replaces `ListItem.Property(Addon.Broken)`.
/// <p>
/// }
+/// \table_row3{ <b>`ListItem.AddonLifecycleType`</b>,
+/// \anchor ListItem_AddonLifecycleType
+/// _string_,
+/// @return String name when the addon is marked as special condition in the repo.
+/// - <b>Label: 24169 (Normal)</b> - Used if an add-on has no special lifecycle state which is the default state
+/// - <b>Label: 24170 (Deprecated)</b> - The add-on should be marked as deprecated but is still usable
+/// - <b>Label: 24171 (Broken)</b> - The add-on should marked as broken in the repository
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link ListItem_AddonLifecycleType `ListItem.AddonLifecycleType`\endlink
+/// replaces `ListItem.AddonBroken`.
+/// <p>
+/// }
+/// \table_row3{ <b>`ListItem.AddonLifecycleDesc`</b>,
+/// \anchor ListItem_AddonLifecycleDesc
+/// _string_,
+/// @return From addon defined message text when it is marked as special condition inside repository.
+/// <p><hr>
+/// @skinning_v19 **[New Infolabel]** \link ListItem_AddonLifecycleDesc `ListItem.AddonLifecycleDesc``\endlink
+/// replaces `ListItem.AddonBroken`.
+/// <p>
+/// }
+
/// \table_row3{ <b>`ListItem.AddonType`</b>,
/// \anchor ListItem_AddonType
/// _string_,
@@ -6662,6 +6776,8 @@ const infomap listitem_labels[]= {{ "thumb", LISTITEM_THUMB },
{ "addondisclaimer", LISTITEM_ADDON_DISCLAIMER },
{ "addonnews", LISTITEM_ADDON_NEWS },
{ "addonbroken", LISTITEM_ADDON_BROKEN },
+ { "addonlifecycletype", LISTITEM_ADDON_LIFECYCLE_TYPE },
+ { "addonlifecycledesc", LISTITEM_ADDON_LIFECYCLE_DESC },
{ "addontype", LISTITEM_ADDON_TYPE },
{ "addoninstalldate", LISTITEM_ADDON_INSTALL_DATE },
{ "addonlastupdated", LISTITEM_ADDON_LAST_UPDATED },
@@ -6689,6 +6805,7 @@ const infomap listitem_labels[]= {{ "thumb", LISTITEM_THUMB },
{ "islive", LISTITEM_IS_LIVE },
{ "tvshowdbid", LISTITEM_TVSHOWDBID },
{ "albumstatus", LISTITEM_ALBUMSTATUS },
+ { "isautoupdateable", LISTITEM_ISAUTOUPDATEABLE },
};
/// \page modules__infolabels_boolean_conditions
@@ -9259,6 +9376,11 @@ const infomap slideshow[] = {{ "ispaused", SLIDESHOW_ISPAUSED
/// \page modules__infolabels_boolean_conditions
/// \section modules_rm_infolabels_booleans Additional revision history for Infolabels and Boolean Conditions
/// <hr>
+/// \subsection modules_rm_infolabels_booleans_v19 Kodi v19 (Matrix)
+/// @skinning_v19 **[Removed Infolabels]** The following infolabels have been removed:
+/// - `System.Platform.Linux.RaspberryPi` - use \link System_Platform_Linux `System.Platform.Linux`\endlink instead
+///
+/// <hr>
/// \subsection modules_rm_infolabels_booleans_v18 Kodi v18 (Leia)
///
/// @skinning_v18 **[Removed Infolabels]** The following infolabels have been removed:
@@ -9909,15 +10031,7 @@ int CGUIInfoManager::TranslateSingleString(const std::string &strCondition, bool
{ //! @todo replace with a single system.platform
std::string platform = info[2].name;
if (platform == "linux")
- {
- if (info.size() == 4)
- {
- std::string device = info[3].name;
- if (device == "raspberrypi")
- return SYSTEM_PLATFORM_LINUX_RASPBERRY_PI;
- }
- else return SYSTEM_PLATFORM_LINUX;
- }
+ return SYSTEM_PLATFORM_LINUX;
else if (platform == "windows")
return SYSTEM_PLATFORM_WINDOWS;
else if (platform == "uwp")
@@ -9963,6 +10077,21 @@ int CGUIInfoManager::TranslateSingleString(const std::string &strCondition, bool
return AddMultiInfo(CGUIInfo(value, 1, position)); // 1 => relative
}
}
+ else if (info[0].name == "player")
+ { //! @todo these two don't allow duration(foo) and also don't allow more than this number of levels...
+ if (info[1].name == "position")
+ {
+ int position = atoi(info[1].param().c_str());
+ int value = TranslatePlayerString(info[2].name); // player.position(foo).bar
+ return AddMultiInfo(CGUIInfo(value, 2, position)); // 2 => absolute (0 used for not set)
+ }
+ else if (info[1].name == "offset")
+ {
+ int position = atoi(info[1].param().c_str());
+ int value = TranslatePlayerString(info[2].name); // player.offset(foo).bar
+ return AddMultiInfo(CGUIInfo(value, 1, position)); // 1 => relative
+ }
+ }
else if (info[0].name == "container")
{
if (info[1].name == "listitem" ||
@@ -10079,6 +10208,16 @@ int CGUIInfoManager::TranslateVideoPlayerString(const std::string& info) const
return 0;
}
+int CGUIInfoManager::TranslatePlayerString(const std::string& info) const
+{
+ for (const infomap& i : player_labels)
+ {
+ if (info == i.str)
+ return i.val;
+ }
+ return 0;
+}
+
TIME_FORMAT CGUIInfoManager::TranslateTimeFormat(const std::string &format)
{
if (format.empty())
diff --git a/xbmc/GUIInfoManager.h b/xbmc/GUIInfoManager.h
index 8f9403f7c4..9206dc0aee 100644
--- a/xbmc/GUIInfoManager.h
+++ b/xbmc/GUIInfoManager.h
@@ -174,6 +174,7 @@ private:
int TranslateListItem(const Property& cat, const Property& prop, int id, bool container);
int TranslateMusicPlayerString(const std::string &info) const;
int TranslateVideoPlayerString(const std::string& info) const;
+ int TranslatePlayerString(const std::string& info) const;
static TIME_FORMAT TranslateTimeFormat(const std::string &format);
std::string GetMultiInfoLabel(const KODI::GUILIB::GUIINFO::CGUIInfo &info, int contextWindow, std::string *fallback = nullptr) const;
diff --git a/xbmc/LangInfo.cpp b/xbmc/LangInfo.cpp
index 70699bc15b..c6a430afd1 100644
--- a/xbmc/LangInfo.cpp
+++ b/xbmc/LangInfo.cpp
@@ -661,17 +661,29 @@ bool CLangInfo::SetLanguage(std::string language /* = "" */, bool reloadServices
if (language.empty())
language = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOCALE_LANGUAGE);
+ auto& addonMgr = CServiceBroker::GetAddonMgr();
ADDON::AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(language, addon, ADDON::ADDON_RESOURCE_LANGUAGE, false))
- {
- CLog::Log(LOGWARNING, "CLangInfo: could not find language add-on '%s', loading default..", language.c_str());
- language = std::static_pointer_cast<const CSettingString>(CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(
- CSettings::SETTING_LOCALE_LANGUAGE))->GetDefault();
- if (!CServiceBroker::GetAddonMgr().GetAddon(language, addon, ADDON::ADDON_RESOURCE_LANGUAGE, false))
+ // Find the chosen language add-on if it's enabled
+ if (!addonMgr.GetAddon(language, addon, ADDON::ADDON_RESOURCE_LANGUAGE, true))
+ {
+ if (!addonMgr.IsAddonInstalled(language) ||
+ (addonMgr.IsAddonDisabled(language) && !addonMgr.EnableAddon(language)))
{
- CLog::Log(LOGFATAL, "CLangInfo: could not find default language add-on '%s'", language.c_str());
- return false;
+ CLog::Log(LOGWARNING,
+ "CLangInfo::{}: could not find or enable language add-on '{}', loading default...",
+ __func__, language);
+ language = std::static_pointer_cast<const CSettingString>(
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(
+ CSettings::SETTING_LOCALE_LANGUAGE))
+ ->GetDefault();
+
+ if (!addonMgr.GetAddon(language, addon, ADDON::ADDON_RESOURCE_LANGUAGE, false))
+ {
+ CLog::Log(LOGFATAL, "CLangInfo::{}: could not find default language add-on '{}'", __func__,
+ language);
+ return false;
+ }
}
}
diff --git a/xbmc/SystemGlobals.cpp b/xbmc/SystemGlobals.cpp
index 435b1f5090..6bb854cc42 100644
--- a/xbmc/SystemGlobals.cpp
+++ b/xbmc/SystemGlobals.cpp
@@ -24,10 +24,6 @@ std::map<std::string, std::string> CSpecialProtocol::m_pathMap;
#include "filesystem/ZipManager.h"
-#ifdef TARGET_RASPBERRY_PI
-#include "platform/linux/RBP.h"
-#endif
-
CLangCodeExpander g_LangCodeExpander;
CLocalizeStrings g_localizeStrings;
CLocalizeStrings g_localizeStringsTemp;
@@ -42,8 +38,4 @@ std::map<std::string, std::string> CSpecialProtocol::m_pathMap;
CAlarmClock g_alarmClock;
CSectionLoader g_sectionLoader;
-#ifdef TARGET_RASPBERRY_PI
- CRBP g_RBP;
-#endif
-
CZipManager g_ZipManager;
diff --git a/xbmc/TextureCacheJob.cpp b/xbmc/TextureCacheJob.cpp
index 7afe6a49ff..f1f3d25ee0 100644
--- a/xbmc/TextureCacheJob.cpp
+++ b/xbmc/TextureCacheJob.cpp
@@ -22,9 +22,6 @@
#include "FileItem.h"
#include "music/MusicThumbLoader.h"
#include "music/tags/MusicInfoTag.h"
-#if defined(TARGET_RASPBERRY_PI)
-#include "cores/omxplayer/OMXImage.h"
-#endif
#include <inttypes.h>
@@ -80,20 +77,6 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
else if (m_details.hash == m_oldHash)
return true;
-#if defined(TARGET_RASPBERRY_PI)
- if (COMXImage::CreateThumb(image, width, height, additional_info, CTextureCache::GetCachedPath(m_cachePath + ".jpg")))
- {
- m_details.width = width;
- m_details.height = height;
- m_details.file = m_cachePath + ".jpg";
- if (out_texture)
- *out_texture = LoadImage(CTextureCache::GetCachedPath(m_details.file), width, height, "" /* already flipped */);
- CLog::Log(LOGDEBUG, "Fast %s image '%s' to '%s': %p",
- m_oldHash.empty() ? "Caching" : "Recaching", CURL::GetRedacted(image),
- m_details.file, static_cast<void*>(out_texture));
- return true;
- }
-#endif
CBaseTexture *texture = LoadImage(image, width, height, additional_info, true);
if (texture)
{
diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp
index 4eac37e9e5..fbb5e16c74 100644
--- a/xbmc/Util.cpp
+++ b/xbmc/Util.cpp
@@ -59,24 +59,24 @@
#include "CompileInfo.h"
#include "platform/darwin/DarwinUtils.h"
#endif
+#include "URL.h"
+#include "cores/VideoPlayer/DVDSubtitles/DVDSubtitleStream.h"
+#include "cores/VideoPlayer/DVDSubtitles/DVDSubtitleTagSami.h"
#include "filesystem/File.h"
+#include "guilib/LocalizeStrings.h"
+#include "platform/Environment.h"
+#include "settings/AdvancedSettings.h"
#include "settings/MediaSettings.h"
#include "settings/Settings.h"
-#include "utils/StringUtils.h"
-#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
-#include "guilib/LocalizeStrings.h"
#include "utils/Digest.h"
#include "utils/FileExtensionProvider.h"
+#include "utils/LangCodeExpander.h"
+#include "utils/StringUtils.h"
#include "utils/TimeUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
-#include "platform/Environment.h"
-
-#include "cores/VideoPlayer/DVDSubtitles/DVDSubtitleTagSami.h"
-#include "cores/VideoPlayer/DVDSubtitles/DVDSubtitleStream.h"
-#include "URL.h"
-#include "utils/LangCodeExpander.h"
+#include "video/VideoDatabase.h"
#include "video/VideoInfoTag.h"
#ifdef HAVE_LIBCAP
#include <sys/capability.h>
@@ -2311,7 +2311,20 @@ void CUtil::ScanForExternalAudio(const std::string& videoPath, std::vector<std::
GetItemsToScan(strBasePath, CServiceBroker::GetFileExtensionProvider().GetMusicExtensions(), common_sub_dirs, items);
std::vector<std::string> exts = StringUtils::Split(CServiceBroker::GetFileExtensionProvider().GetMusicExtensions(), "|");
- ScanPathsForAssociatedItems(strAudio, items, exts, vecAudio);
+
+ CVideoDatabase database;
+ database.Open();
+ bool useAllExternalAudio = database.GetUseAllExternalAudioForVideo(videoPath);
+
+ if (useAllExternalAudio)
+ {
+ for (const auto& audioItem : items.GetList())
+ {
+ vecAudio.push_back(audioItem.get()->GetPath());
+ }
+ }
+ else
+ ScanPathsForAssociatedItems(strAudio, items, exts, vecAudio);
}
bool CUtil::CanBindPrivileged()
diff --git a/xbmc/XBDateTime.cpp b/xbmc/XBDateTime.cpp
index dd1b0ce8a9..89f4897f47 100644
--- a/xbmc/XBDateTime.cpp
+++ b/xbmc/XBDateTime.cpp
@@ -17,10 +17,10 @@
#include <cstdlib>
-#define SECONDS_PER_DAY 86400UL
-#define SECONDS_PER_HOUR 3600UL
-#define SECONDS_PER_MINUTE 60UL
-#define SECONDS_TO_FILETIME 10000000UL
+#define SECONDS_PER_DAY 86400L
+#define SECONDS_PER_HOUR 3600L
+#define SECONDS_PER_MINUTE 60L
+#define SECONDS_TO_FILETIME 10000000L
static const char *DAY_NAMES[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static const char *MONTH_NAMES[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
@@ -81,15 +81,15 @@ CDateTimeSpan CDateTimeSpan::operator +(const CDateTimeSpan& right) const
{
CDateTimeSpan left(*this);
- ULARGE_INTEGER timeLeft;
- left.ToULargeInt(timeLeft);
+ LARGE_INTEGER timeLeft;
+ left.ToLargeInt(timeLeft);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeLeft.QuadPart+=timeRight.QuadPart;
- left.FromULargeInt(timeLeft);
+ left.FromLargeInt(timeLeft);
return left;
}
@@ -98,56 +98,56 @@ CDateTimeSpan CDateTimeSpan::operator -(const CDateTimeSpan& right) const
{
CDateTimeSpan left(*this);
- ULARGE_INTEGER timeLeft;
- left.ToULargeInt(timeLeft);
+ LARGE_INTEGER timeLeft;
+ left.ToLargeInt(timeLeft);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeLeft.QuadPart-=timeRight.QuadPart;
- left.FromULargeInt(timeLeft);
+ left.FromLargeInt(timeLeft);
return left;
}
const CDateTimeSpan& CDateTimeSpan::operator +=(const CDateTimeSpan& right)
{
- ULARGE_INTEGER timeThis;
- ToULargeInt(timeThis);
+ LARGE_INTEGER timeThis;
+ ToLargeInt(timeThis);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeThis.QuadPart+=timeRight.QuadPart;
- FromULargeInt(timeThis);
+ FromLargeInt(timeThis);
return *this;
}
const CDateTimeSpan& CDateTimeSpan::operator -=(const CDateTimeSpan& right)
{
- ULARGE_INTEGER timeThis;
- ToULargeInt(timeThis);
+ LARGE_INTEGER timeThis;
+ ToLargeInt(timeThis);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeThis.QuadPart-=timeRight.QuadPart;
- FromULargeInt(timeThis);
+ FromLargeInt(timeThis);
return *this;
}
-void CDateTimeSpan::ToULargeInt(ULARGE_INTEGER& time) const
+void CDateTimeSpan::ToLargeInt(LARGE_INTEGER& time) const
{
time.u.HighPart = m_timeSpan.highDateTime;
time.u.LowPart = m_timeSpan.lowDateTime;
}
-void CDateTimeSpan::FromULargeInt(const ULARGE_INTEGER& time)
+void CDateTimeSpan::FromLargeInt(const LARGE_INTEGER& time)
{
m_timeSpan.highDateTime = time.u.HighPart;
m_timeSpan.lowDateTime = time.u.LowPart;
@@ -155,15 +155,15 @@ void CDateTimeSpan::FromULargeInt(const ULARGE_INTEGER& time)
void CDateTimeSpan::SetDateTimeSpan(int day, int hour, int minute, int second)
{
- ULARGE_INTEGER time;
- ToULargeInt(time);
+ LARGE_INTEGER time;
+ ToLargeInt(time);
time.QuadPart= static_cast<long long>(day) *SECONDS_PER_DAY*SECONDS_TO_FILETIME;
time.QuadPart+= static_cast<long long>(hour) *SECONDS_PER_HOUR*SECONDS_TO_FILETIME;
time.QuadPart+= static_cast<long long>(minute) *SECONDS_PER_MINUTE*SECONDS_TO_FILETIME;
time.QuadPart+= static_cast<long long>(second) *SECONDS_TO_FILETIME;
- FromULargeInt(time);
+ FromLargeInt(time);
}
void CDateTimeSpan::SetFromTimeString(const std::string& time) // hh:mm
@@ -178,40 +178,40 @@ void CDateTimeSpan::SetFromTimeString(const std::string& time) // hh:mm
int CDateTimeSpan::GetDays() const
{
- ULARGE_INTEGER time;
- ToULargeInt(time);
+ LARGE_INTEGER time;
+ ToLargeInt(time);
return (int)(time.QuadPart/SECONDS_TO_FILETIME)/SECONDS_PER_DAY;
}
int CDateTimeSpan::GetHours() const
{
- ULARGE_INTEGER time;
- ToULargeInt(time);
+ LARGE_INTEGER time;
+ ToLargeInt(time);
return (int)((time.QuadPart/SECONDS_TO_FILETIME)%SECONDS_PER_DAY)/SECONDS_PER_HOUR;
}
int CDateTimeSpan::GetMinutes() const
{
- ULARGE_INTEGER time;
- ToULargeInt(time);
+ LARGE_INTEGER time;
+ ToLargeInt(time);
return (int)((time.QuadPart/SECONDS_TO_FILETIME%SECONDS_PER_DAY)%SECONDS_PER_HOUR)/SECONDS_PER_MINUTE;
}
int CDateTimeSpan::GetSeconds() const
{
- ULARGE_INTEGER time;
- ToULargeInt(time);
+ LARGE_INTEGER time;
+ ToLargeInt(time);
return (int)(((time.QuadPart/SECONDS_TO_FILETIME%SECONDS_PER_DAY)%SECONDS_PER_HOUR)%SECONDS_PER_MINUTE)%SECONDS_PER_MINUTE;
}
int CDateTimeSpan::GetSecondsTotal() const
{
- ULARGE_INTEGER time;
- ToULargeInt(time);
+ LARGE_INTEGER time;
+ ToLargeInt(time);
return (int)(time.QuadPart/SECONDS_TO_FILETIME);
}
@@ -502,15 +502,15 @@ CDateTime CDateTime::operator +(const CDateTimeSpan& right) const
{
CDateTime left(*this);
- ULARGE_INTEGER timeLeft;
- left.ToULargeInt(timeLeft);
+ LARGE_INTEGER timeLeft;
+ left.ToLargeInt(timeLeft);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeLeft.QuadPart+=timeRight.QuadPart;
- left.FromULargeInt(timeLeft);
+ left.FromLargeInt(timeLeft);
return left;
}
@@ -519,45 +519,45 @@ CDateTime CDateTime::operator -(const CDateTimeSpan& right) const
{
CDateTime left(*this);
- ULARGE_INTEGER timeLeft;
- left.ToULargeInt(timeLeft);
+ LARGE_INTEGER timeLeft;
+ left.ToLargeInt(timeLeft);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeLeft.QuadPart-=timeRight.QuadPart;
- left.FromULargeInt(timeLeft);
+ left.FromLargeInt(timeLeft);
return left;
}
const CDateTime& CDateTime::operator +=(const CDateTimeSpan& right)
{
- ULARGE_INTEGER timeThis;
- ToULargeInt(timeThis);
+ LARGE_INTEGER timeThis;
+ ToLargeInt(timeThis);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeThis.QuadPart+=timeRight.QuadPart;
- FromULargeInt(timeThis);
+ FromLargeInt(timeThis);
return *this;
}
const CDateTime& CDateTime::operator -=(const CDateTimeSpan& right)
{
- ULARGE_INTEGER timeThis;
- ToULargeInt(timeThis);
+ LARGE_INTEGER timeThis;
+ ToLargeInt(timeThis);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeThis.QuadPart-=timeRight.QuadPart;
- FromULargeInt(timeThis);
+ FromLargeInt(timeThis);
return *this;
}
@@ -566,18 +566,18 @@ CDateTimeSpan CDateTime::operator -(const CDateTime& right) const
{
CDateTimeSpan left;
- ULARGE_INTEGER timeLeft;
- left.ToULargeInt(timeLeft);
+ LARGE_INTEGER timeLeft;
+ left.ToLargeInt(timeLeft);
- ULARGE_INTEGER timeThis;
- ToULargeInt(timeThis);
+ LARGE_INTEGER timeThis;
+ ToLargeInt(timeThis);
- ULARGE_INTEGER timeRight;
- right.ToULargeInt(timeRight);
+ LARGE_INTEGER timeRight;
+ right.ToLargeInt(timeRight);
timeLeft.QuadPart=timeThis.QuadPart-timeRight.QuadPart;
- left.FromULargeInt(timeLeft);
+ left.FromLargeInt(timeLeft);
return left;
}
@@ -663,13 +663,13 @@ bool CDateTime::ToFileTime(const tm& time, KODI::TIME::FileTime& fileTime) const
return SystemTimeToFileTime(&st, &fileTime) == 1;
}
-void CDateTime::ToULargeInt(ULARGE_INTEGER& time) const
+void CDateTime::ToLargeInt(LARGE_INTEGER& time) const
{
time.u.HighPart = m_time.highDateTime;
time.u.LowPart = m_time.lowDateTime;
}
-void CDateTime::FromULargeInt(const ULARGE_INTEGER& time)
+void CDateTime::FromLargeInt(const LARGE_INTEGER& time)
{
m_time.highDateTime = time.u.HighPart;
m_time.lowDateTime = time.u.LowPart;
diff --git a/xbmc/XBDateTime.h b/xbmc/XBDateTime.h
index c70c838604..491db5a4eb 100644
--- a/xbmc/XBDateTime.h
+++ b/xbmc/XBDateTime.h
@@ -106,8 +106,8 @@ public:
int GetSecondsTotal() const;
private:
- void ToULargeInt(ULARGE_INTEGER& time) const;
- void FromULargeInt(const ULARGE_INTEGER& time);
+ void ToLargeInt(LARGE_INTEGER& time) const;
+ void FromLargeInt(const LARGE_INTEGER& time);
private:
KODI::TIME::FileTime m_timeSpan;
@@ -252,8 +252,8 @@ private:
bool ToFileTime(const time_t& time, KODI::TIME::FileTime& fileTime) const;
bool ToFileTime(const tm& time, KODI::TIME::FileTime& fileTime) const;
- void ToULargeInt(ULARGE_INTEGER& time) const;
- void FromULargeInt(const ULARGE_INTEGER& time);
+ void ToLargeInt(LARGE_INTEGER& time) const;
+ void FromLargeInt(const LARGE_INTEGER& time);
private:
KODI::TIME::FileTime m_time;
diff --git a/xbmc/addons/Addon.h b/xbmc/addons/Addon.h
index e8fed4e5bc..6b72ca62c2 100644
--- a/xbmc/addons/Addon.h
+++ b/xbmc/addons/Addon.h
@@ -98,7 +98,11 @@ public:
ArtMap Art() const override { return m_addonInfo->Art(); }
std::vector<std::string> Screenshots() const override { return m_addonInfo->Screenshots(); };
std::string Disclaimer() const override { return m_addonInfo->Disclaimer(); }
- std::string Broken() const override { return m_addonInfo->Broken(); }
+ AddonLifecycleState LifecycleState() const override { return m_addonInfo->LifecycleState(); }
+ std::string LifecycleStateDescription() const override
+ {
+ return m_addonInfo->LifecycleStateDescription();
+ }
CDateTime InstallDate() const override { return m_addonInfo->InstallDate(); }
CDateTime LastUpdated() const override { return m_addonInfo->LastUpdated(); }
CDateTime LastUsed() const override { return m_addonInfo->LastUsed(); }
diff --git a/xbmc/addons/AddonBindings.cmake b/xbmc/addons/AddonBindings.cmake
index bdb74e8585..11cf190d3f 100644
--- a/xbmc/addons/AddonBindings.cmake
+++ b/xbmc/addons/AddonBindings.cmake
@@ -4,8 +4,6 @@
# Keep this in alphabetical order
set(CORE_ADDON_BINDINGS_FILES
- ${CORE_SOURCE_DIR}/xbmc/input/actions/ActionIDs.h
- ${CORE_SOURCE_DIR}/xbmc/input/XBMC_vkeys.h
)
set(CORE_ADDON_BINDINGS_DIRS
diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp
index c1fe3d7ae8..41d3a95c6e 100644
--- a/xbmc/addons/AddonDatabase.cpp
+++ b/xbmc/addons/AddonDatabase.cpp
@@ -26,12 +26,13 @@
using namespace ADDON;
-static std::string SerializeMetadata(const IAddon& addon)
+std::string CAddonDatabaseSerializer::SerializeMetadata(const CAddonInfo& addon)
{
CVariant variant;
variant["author"] = addon.Author();
variant["disclaimer"] = addon.Disclaimer();
- variant["broken"] = addon.Broken();
+ variant["lifecycletype"] = static_cast<unsigned int>(addon.LifecycleState());
+ variant["lifecycledesc"] = addon.LifecycleStateDescription();
variant["size"] = addon.PackageSize();
variant["path"] = addon.Path();
@@ -46,7 +47,7 @@ static std::string SerializeMetadata(const IAddon& addon)
variant["screenshots"].push_back(item);
variant["extensions"] = CVariant(CVariant::VariantTypeArray);
- variant["extensions"].push_back(ADDON::CAddonInfo::TranslateType(addon.Type(), false));
+ variant["extensions"].push_back(SerializeExtensions(*addon.Type(addon.MainType())));
variant["dependencies"] = CVariant(CVariant::VariantTypeArray);
for (const auto& dep : addon.GetDependencies())
@@ -73,7 +74,42 @@ static std::string SerializeMetadata(const IAddon& addon)
return json;
}
-static void DeserializeMetadata(const std::string& document, CAddonInfoBuilder::CFromDB& builder)
+CVariant CAddonDatabaseSerializer::SerializeExtensions(const CAddonExtensions& addonType)
+{
+ CVariant variant;
+ variant["type"] = addonType.m_point;
+
+ variant["values"] = CVariant(CVariant::VariantTypeArray);
+ for (const auto& value : addonType.m_values)
+ {
+ CVariant info(CVariant::VariantTypeObject);
+ info["id"] = value.first;
+ info["content"] = CVariant(CVariant::VariantTypeArray);
+ for (const auto& content : value.second)
+ {
+ CVariant contentEntry(CVariant::VariantTypeObject);
+ contentEntry["key"] = content.first;
+ contentEntry["value"] = content.second.str;
+ info["content"].push_back(std::move(contentEntry));
+ }
+
+ variant["values"].push_back(std::move(info));
+ }
+
+ variant["children"] = CVariant(CVariant::VariantTypeArray);
+ for (auto& child : addonType.m_children)
+ {
+ CVariant info(CVariant::VariantTypeObject);
+ info["id"] = child.first;
+ info["child"] = SerializeExtensions(child.second);
+ variant["children"].push_back(std::move(info));
+ }
+
+ return variant;
+}
+
+void CAddonDatabaseSerializer::DeserializeMetadata(const std::string& document,
+ CAddonInfoBuilder::CFromDB& builder)
{
CVariant variant;
if (!CJSONVariantParser::Parse(document, variant))
@@ -81,7 +117,9 @@ static void DeserializeMetadata(const std::string& document, CAddonInfoBuilder::
builder.SetAuthor(variant["author"].asString());
builder.SetDisclaimer(variant["disclaimer"].asString());
- builder.SetBroken(variant["broken"].asString());
+ builder.SetLifecycleState(
+ static_cast<AddonLifecycleState>(variant["lifecycletype"].asUnsignedInteger()),
+ variant["lifecycledesc"].asString());
builder.SetPackageSize(variant["size"].asUnsignedInteger());
builder.SetPath(variant["path"].asString());
@@ -97,7 +135,10 @@ static void DeserializeMetadata(const std::string& document, CAddonInfoBuilder::
screenshots.push_back(it->asString());
builder.SetScreenshots(std::move(screenshots));
- builder.SetType(CAddonInfo::TranslateType(variant["extensions"][0].asString()));
+ CAddonType addonType;
+ DeserializeExtensions(variant["extensions"][0], addonType);
+ addonType.m_type = CAddonInfo::TranslateType(addonType.m_point);
+ builder.SetExtensions(std::move(addonType));
{
std::vector<DependencyInfo> deps;
@@ -115,6 +156,37 @@ static void DeserializeMetadata(const std::string& document, CAddonInfoBuilder::
builder.SetExtrainfo(std::move(extraInfo));
}
+void CAddonDatabaseSerializer::DeserializeExtensions(const CVariant& variant,
+ CAddonExtensions& addonType)
+{
+ addonType.m_point = variant["type"].asString();
+
+ for (auto value = variant["values"].begin_array(); value != variant["values"].end_array();
+ ++value)
+ {
+ std::string id = (*value)["id"].asString();
+ std::vector<std::pair<std::string, SExtValue>> extValues;
+ for (auto content = (*value)["content"].begin_array();
+ content != (*value)["content"].end_array(); ++content)
+ {
+ extValues.emplace_back((*content)["key"].asString(), (*content)["value"].asString());
+ }
+
+ addonType.m_values.emplace_back(id, extValues);
+ }
+
+ for (auto child = variant["children"].begin_array(); child != variant["children"].end_array();
+ ++child)
+ {
+ CAddonExtensions childExt;
+ DeserializeExtensions((*child)["child"], childExt);
+ std::string id = (*child)["id"].asString();
+ addonType.m_children.emplace_back(id, childExt);
+ }
+
+ return;
+}
+
CAddonDatabase::CAddonDatabase() = default;
CAddonDatabase::~CAddonDatabase() = default;
@@ -131,7 +203,7 @@ int CAddonDatabase::GetMinSchemaVersion() const
int CAddonDatabase::GetSchemaVersion() const
{
- return 31;
+ return 33;
}
void CAddonDatabase::CreateTables()
@@ -154,8 +226,9 @@ void CAddonDatabase::CreateTables()
CLog::Log(LOGINFO, "create addonlinkrepo table");
m_pDS->exec("CREATE TABLE addonlinkrepo (idRepo integer, idAddon integer)\n");
- CLog::Log(LOGINFO, "create blacklist table");
- m_pDS->exec("CREATE TABLE blacklist (id integer primary key, addonID text)\n");
+ CLog::Log(LOGINFO, "create update_rules table");
+ m_pDS->exec(
+ "CREATE TABLE update_rules (id integer primary key, addonID TEXT, updateRule INTEGER)\n");
CLog::Log(LOGINFO, "create package table");
m_pDS->exec("CREATE TABLE package (id integer primary key, addonID text, filename text, hash text)\n");
@@ -172,7 +245,7 @@ void CAddonDatabase::CreateAnalytics()
m_pDS->exec("CREATE INDEX idxAddons ON addons(addonID)");
m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_1 ON addonlinkrepo ( idAddon, idRepo )\n");
m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_2 ON addonlinkrepo ( idRepo, idAddon )\n");
- m_pDS->exec("CREATE UNIQUE INDEX idxBlack ON blacklist(addonID)");
+ m_pDS->exec("CREATE UNIQUE INDEX idxUpdate_rules ON update_rules(addonID, updateRule)");
m_pDS->exec("CREATE UNIQUE INDEX idxPackage ON package(filename)");
}
@@ -233,6 +306,79 @@ void CAddonDatabase::UpdateTables(int version)
m_pDS->exec("UPDATE installed SET origin = addonID WHERE (origin='') AND "
"EXISTS (SELECT * FROM repo WHERE repo.addonID = installed.addonID)");
}
+ if (version < 32)
+ {
+ m_pDS->exec(
+ "CREATE TABLE update_rules (id integer primary key, addonID text, updateRule INTEGER)");
+ m_pDS->exec("INSERT INTO update_rules (addonID, updateRule) SELECT addonID, 1 updateRule FROM "
+ "blacklist");
+ m_pDS->exec("DROP INDEX IF EXISTS idxBlack");
+ m_pDS->exec("DROP TABLE blacklist");
+ }
+ if (version < 33)
+ {
+ m_pDS->query(PrepareSQL("SELECT * FROM addons"));
+ while (!m_pDS->eof())
+ {
+ const int id = m_pDS->fv("id").get_asInt();
+ const std::string metadata = m_pDS->fv("metadata").get_asString();
+
+ CVariant variant;
+ if (!CJSONVariantParser::Parse(metadata, variant))
+ continue;
+
+ // Replace obsolete "broken" with new in json text
+ if (variant.isMember("broken") && variant["broken"].asString().empty())
+ {
+ variant["lifecycletype"] = static_cast<unsigned int>(AddonLifecycleState::BROKEN);
+ variant["lifecycledesc"] = variant["broken"].asString();
+ variant.erase("broken");
+ }
+
+ // Fix wrong added change about "broken" to "lifecycle..." (request 18286)
+ // as there was every addon marked as broken. This checks his text and if
+ // them empty, becomes it declared as normal.
+ if (variant.isMember("lifecycledesc") && variant.isMember("lifecycletype") &&
+ variant["lifecycledesc"].asString().empty() &&
+ variant["lifecycletype"].asUnsignedInteger() !=
+ static_cast<unsigned int>(AddonLifecycleState::NORMAL))
+ {
+ variant["lifecycletype"] = static_cast<unsigned int>(AddonLifecycleState::NORMAL);
+ }
+
+ CVariant variantUpdate;
+ variantUpdate["type"] = variant["extensions"][0].asString();
+ variantUpdate["values"] = CVariant(CVariant::VariantTypeArray);
+ variantUpdate["children"] = CVariant(CVariant::VariantTypeArray);
+
+ for (auto it = variant["extrainfo"].begin_array(); it != variant["extrainfo"].end_array();
+ ++it)
+ {
+ if ((*it)["key"].asString() == "provides")
+ {
+ CVariant info(CVariant::VariantTypeObject);
+ info["id"] = (*it)["key"].asString();
+ info["content"] = CVariant(CVariant::VariantTypeArray);
+
+ CVariant contentEntry(CVariant::VariantTypeObject);
+ contentEntry["key"] = (*it)["key"].asString();
+ contentEntry["value"] = (*it)["value"].asString();
+ info["content"].push_back(std::move(contentEntry));
+
+ variantUpdate["values"].push_back(std::move(info));
+ break;
+ }
+ }
+ variant["extensions"][0] = variantUpdate;
+
+ std::string json;
+ CJSONVariantWriter::Write(variant, json, true);
+ m_pDS->exec(PrepareSQL("UPDATE addons SET metadata='%s' WHERE id=%i", json.c_str(), id));
+
+ m_pDS->next();
+ }
+ m_pDS->close();
+ }
}
void CAddonDatabase::SyncInstalled(const std::set<std::string>& ids,
@@ -282,7 +428,7 @@ void CAddonDatabase::SyncInstalled(const std::set<std::string>& ids,
for (const auto& id : removed)
{
m_pDS->exec(PrepareSQL("DELETE FROM installed WHERE addonID='%s'", id.c_str()));
- RemoveAddonFromBlacklist(id);
+ RemoveAllUpdateRulesForAddon(id);
DeleteRepository(id);
}
@@ -419,7 +565,7 @@ bool CAddonDatabase::FindByAddonId(const std::string& addonId, ADDON::VECADDONS&
builder.SetName(m_pDS->fv("name").get_asString());
builder.SetSummary(m_pDS->fv("summary").get_asString());
builder.SetDescription(m_pDS->fv("description").get_asString());
- DeserializeMetadata(m_pDS->fv("metadata").get_asString(), builder);
+ CAddonDatabaseSerializer::DeserializeMetadata(m_pDS->fv("metadata").get_asString(), builder);
builder.SetChangelog(m_pDS->fv("news").get_asString());
builder.SetOrigin(m_pDS->fv("repoID").get_asString());
@@ -566,7 +712,7 @@ bool CAddonDatabase::GetAddon(int id, AddonPtr &addon)
builder.SetName(m_pDS2->fv("name").get_asString());
builder.SetSummary(m_pDS2->fv("summary").get_asString());
builder.SetDescription(m_pDS2->fv("description").get_asString());
- DeserializeMetadata(m_pDS2->fv("metadata").get_asString(), builder);
+ CAddonDatabaseSerializer::DeserializeMetadata(m_pDS2->fv("metadata").get_asString(), builder);
addon = CAddonBuilder::Generate(builder.get(), ADDON_UNKNOWN);
return addon != nullptr;
@@ -650,7 +796,7 @@ bool CAddonDatabase::GetRepositoryContent(const std::string& id, VECADDONS& addo
builder.SetSummary(m_pDS->fv("summary").get_asString());
builder.SetDescription(m_pDS->fv("description").get_asString());
builder.SetOrigin(m_pDS->fv("repoID").get_asString());
- DeserializeMetadata(m_pDS->fv("metadata").get_asString(), builder);
+ CAddonDatabaseSerializer::DeserializeMetadata(m_pDS->fv("metadata").get_asString(), builder);
auto addon = CAddonBuilder::Generate(builder.get(), ADDON_UNKNOWN);
if (addon)
@@ -731,8 +877,10 @@ int CAddonDatabase::GetRepositoryId(const std::string& addonId)
return m_pDS->fv("id").get_asInt();
}
-bool CAddonDatabase::UpdateRepositoryContent(const std::string& repository, const AddonVersion& version,
- const std::string& checksum, const std::vector<AddonPtr>& addons)
+bool CAddonDatabase::UpdateRepositoryContent(const std::string& repository,
+ const AddonVersion& version,
+ const std::string& checksum,
+ const std::vector<AddonInfoPtr>& addons)
{
try
{
@@ -756,13 +904,9 @@ bool CAddonDatabase::UpdateRepositoryContent(const std::string& repository, cons
m_pDS->exec(PrepareSQL(
"INSERT INTO addons (id, metadata, addonID, version, name, summary, description, news) "
"VALUES (NULL, '%s', '%s', '%s', '%s','%s', '%s','%s')",
- SerializeMetadata(*addon).c_str(),
- addon->ID().c_str(),
- addon->Version().asString().c_str(),
- addon->Name().c_str(),
- addon->Summary().c_str(),
- addon->Description().c_str(),
- addon->ChangeLog().c_str()));
+ CAddonDatabaseSerializer::SerializeMetadata(*addon).c_str(), addon->ID().c_str(),
+ addon->Version().asString().c_str(), addon->Name().c_str(), addon->Summary().c_str(),
+ addon->Description().c_str(), addon->ChangeLog().c_str()));
int idAddon = static_cast<int>(m_pDS->lastinsertid());
if (idAddon <= 0)
@@ -985,7 +1129,8 @@ bool CAddonDatabase::GetDisabled(std::map<std::string, AddonDisabledReason>& add
return false;
}
-bool CAddonDatabase::GetBlacklisted(std::set<std::string>& addons)
+bool CAddonDatabase::GetAddonUpdateRules(
+ std::map<std::string, std::vector<AddonUpdateRule>>& rulesMap) const
{
try
{
@@ -994,11 +1139,12 @@ bool CAddonDatabase::GetBlacklisted(std::set<std::string>& addons)
if (!m_pDS)
return false;
- std::string sql = PrepareSQL("SELECT addonID FROM blacklist");
+ std::string sql = PrepareSQL("SELECT * FROM update_rules");
m_pDS->query(sql);
while (!m_pDS->eof())
{
- addons.insert(m_pDS->fv("addonID").get_asString());
+ rulesMap[m_pDS->fv("addonID").get_asString()].emplace_back(
+ static_cast<AddonUpdateRule>(m_pDS->fv("updateRule").get_asInt()));
m_pDS->next();
}
m_pDS->close();
@@ -1011,7 +1157,7 @@ bool CAddonDatabase::GetBlacklisted(std::set<std::string>& addons)
return false;
}
-bool CAddonDatabase::BlacklistAddon(const std::string& addonID)
+bool CAddonDatabase::AddUpdateRuleForAddon(const std::string& addonID, AddonUpdateRule updateRule)
{
try
{
@@ -1020,7 +1166,9 @@ bool CAddonDatabase::BlacklistAddon(const std::string& addonID)
if (!m_pDS)
return false;
- std::string sql = PrepareSQL("INSERT INTO blacklist(id, addonID) VALUES(NULL, '%s')", addonID.c_str());
+ std::string sql =
+ PrepareSQL("INSERT INTO update_rules(id, addonID, updateRule) VALUES(NULL, '%s', %d)",
+ addonID.c_str(), static_cast<int>(updateRule));
m_pDS->exec(sql);
return true;
}
@@ -1031,7 +1179,13 @@ bool CAddonDatabase::BlacklistAddon(const std::string& addonID)
return false;
}
-bool CAddonDatabase::RemoveAddonFromBlacklist(const std::string& addonID)
+bool CAddonDatabase::RemoveAllUpdateRulesForAddon(const std::string& addonID)
+{
+ return RemoveUpdateRuleForAddon(addonID, AddonUpdateRule::ANY);
+}
+
+bool CAddonDatabase::RemoveUpdateRuleForAddon(const std::string& addonID,
+ AddonUpdateRule updateRule)
{
try
{
@@ -1040,7 +1194,13 @@ bool CAddonDatabase::RemoveAddonFromBlacklist(const std::string& addonID)
if (!m_pDS)
return false;
- std::string sql = PrepareSQL("DELETE FROM blacklist WHERE addonID='%s'", addonID.c_str());
+ std::string sql = PrepareSQL("DELETE FROM update_rules WHERE addonID='%s'", addonID.c_str());
+
+ if (updateRule != AddonUpdateRule::ANY)
+ {
+ sql += PrepareSQL(" AND updateRule = %d", static_cast<int>(updateRule));
+ }
+
m_pDS->exec(sql);
return true;
}
@@ -1079,7 +1239,7 @@ bool CAddonDatabase::RemovePackage(const std::string& packageFileName)
void CAddonDatabase::OnPostUnInstall(const std::string& addonId)
{
- RemoveAddonFromBlacklist(addonId);
+ RemoveAllUpdateRulesForAddon(addonId);
DeleteRepository(addonId);
//! @todo should be done before uninstall to avoid any race conditions
diff --git a/xbmc/addons/AddonDatabase.h b/xbmc/addons/AddonDatabase.h
index 35ba96f80b..101a330f9b 100644
--- a/xbmc/addons/AddonDatabase.h
+++ b/xbmc/addons/AddonDatabase.h
@@ -11,6 +11,7 @@
#include "AddonBuilder.h"
#include "FileItem.h"
#include "addons/Addon.h"
+#include "addons/addoninfo/AddonInfoBuilder.h"
#include "dbwrappers/Database.h"
#include <string>
@@ -19,6 +20,28 @@
namespace ADDON
{
+/*!
+ * @brief Addon content serializer/deserializer.
+ *
+ * Used to save data from the add-on in the database using json format.
+ * The corresponding field in SQL is "addons" for "metadata".
+ *
+ * @warning Changes in the json format need a way to update the addon database
+ * for users, otherwise problems may occur when reading the old content.
+ */
+class CAddonDatabaseSerializer
+{
+ CAddonDatabaseSerializer() = delete;
+
+public:
+ static std::string SerializeMetadata(const CAddonInfo& addon);
+ static void DeserializeMetadata(const std::string& document, CAddonInfoBuilder::CFromDB& builder);
+
+private:
+ static CVariant SerializeExtensions(const CAddonExtensions& addonType);
+ static void DeserializeExtensions(const CVariant& document, CAddonExtensions& addonType);
+};
+
class CAddonDatabase : public CDatabase
{
public:
@@ -45,8 +68,10 @@ public:
/*! Returns all addons in the repositories with id `addonId`. */
bool FindByAddonId(const std::string& addonId, ADDON::VECADDONS& addons) const;
- bool UpdateRepositoryContent(const std::string& repositoryId, const ADDON::AddonVersion& version,
- const std::string& checksum, const std::vector<ADDON::AddonPtr>& addons);
+ bool UpdateRepositoryContent(const std::string& repositoryId,
+ const ADDON::AddonVersion& version,
+ const std::string& checksum,
+ const std::vector<AddonInfoPtr>& addons);
int GetRepoChecksum(const std::string& id, std::string& checksum);
@@ -117,9 +142,37 @@ public:
*/
bool EnableAddon(const std::string& addonID);
- bool BlacklistAddon(const std::string& addonID);
- bool RemoveAddonFromBlacklist(const std::string& addonID);
- bool GetBlacklisted(std::set<std::string>& addons);
+ /*!
+ * \brief Write dataset with addon-id and rule to the db
+ * \param addonID the addonID
+ * \param updateRule the rule value to be written
+ * \return true on success, false otherwise
+ */
+ bool AddUpdateRuleForAddon(const std::string& addonID, ADDON::AddonUpdateRule updateRule);
+
+ /*!
+ * \brief Remove all rule datasets for an addon-id from the db
+ * \param addonID the addonID
+ * \return true on success, false otherwise
+ */
+ bool RemoveAllUpdateRulesForAddon(const std::string& addonID);
+
+ /*!
+ * \brief Remove a single rule dataset for an addon-id from the db
+ * \note specifying AddonUpdateRule::ANY will remove all rules.
+ * use @ref RemoveAllUpdateRulesForAddon() instead
+ * \param addonID the addonID
+ * \param updateRule the rule to remove
+ * \return true on success, false otherwise
+ */
+ bool RemoveUpdateRuleForAddon(const std::string& addonID, AddonUpdateRule updateRule);
+
+ /*!
+ * \brief Retrieve all rule datasets from db and store them into map
+ * \param rulesMap target map
+ * \return true on success, false otherwise
+ */
+ bool GetAddonUpdateRules(std::map<std::string, std::vector<AddonUpdateRule>>& rulesMap) const;
/*! \brief Store an addon's package filename and that file's hash for future verification
\param addonID id of the addon we're adding a package for
diff --git a/xbmc/addons/AddonEvents.h b/xbmc/addons/AddonEvents.h
index 4d2930fdb4..8d3dcad78c 100644
--- a/xbmc/addons/AddonEvents.h
+++ b/xbmc/addons/AddonEvents.h
@@ -81,5 +81,13 @@ namespace ADDON
{
explicit Unload(std::string id) : AddonEvent(std::move(id)) {}
};
+
+ /**
+ * Emitted after the auto-update state of the add-on has been changed.
+ */
+ struct AutoUpdateStateChanged : AddonEvent
+ {
+ explicit AutoUpdateStateChanged(std::string id) : AddonEvent(std::move(id)) {}
+ };
}
}
diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp
index c089d2858d..835277f112 100644
--- a/xbmc/addons/AddonInstaller.cpp
+++ b/xbmc/addons/AddonInstaller.cpp
@@ -11,6 +11,7 @@
#include "FilesystemInstaller.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h" // for callback
+#include "RepositoryUpdater.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
@@ -653,13 +654,16 @@ bool CAddonInstallJob::DoWork()
// Needed to set origin correctly for new installed addons.
std::string origin;
- if (m_repo) // if we have an origin use it
+ if (m_addon->HasType(ADDON_REPOSITORY))
{
- origin = m_repo->ID();
+ origin = m_addon->ID(); // always set repos origin to itself
+ if (m_isUpdate)
+ CServiceBroker::GetRepositoryUpdater().CheckForUpdates(
+ std::static_pointer_cast<CRepository>(m_addon), false);
}
- else if (m_addon->HasType(ADDON_REPOSITORY))
+ else if (m_repo)
{
- origin = m_addon->ID(); // set origin to addon-id which is the repo itself
+ origin = m_repo->ID(); // else use addons repo as origin
}
CServiceBroker::GetAddonMgr().SetAddonOrigin(m_addon->ID(), origin, m_isUpdate);
@@ -669,12 +673,21 @@ bool CAddonInstallJob::DoWork()
CServiceBroker::GetEventLog().Add(
EventPtr(new CAddonManagementEvent(m_addon, m_isUpdate ? 24065 : 24084)), notify, false);
- if (m_isAutoUpdate && m_addon->IsBroken())
+ if (m_isAutoUpdate && m_addon->LifecycleState() == AddonLifecycleState::BROKEN)
{
CLog::Log(LOGDEBUG, "CAddonInstallJob[%s]: auto-disabling due to being marked as broken", m_addon->ID().c_str());
CServiceBroker::GetAddonMgr().DisableAddon(m_addon->ID(), AddonDisabledReason::USER);
CServiceBroker::GetEventLog().Add(EventPtr(new CAddonManagementEvent(m_addon, 24094)), true, false);
}
+ else if (m_addon->LifecycleState() == AddonLifecycleState::DEPRECATED)
+ {
+ CLog::Log(LOGDEBUG, "CAddonInstallJob[%s]: installed addon marked as deprecated",
+ m_addon->ID().c_str());
+ std::string text =
+ StringUtils::Format(g_localizeStrings.Get(24168), m_addon->LifecycleStateDescription());
+ CServiceBroker::GetEventLog().Add(EventPtr(new CAddonManagementEvent(m_addon, text)), true,
+ false);
+ }
// and we're done!
MarkFinished();
@@ -737,12 +750,19 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const RepositoryP
if (!deps.empty() && m_addon->HasType(ADDON_REPOSITORY))
{
- CLog::Log(
- LOGERROR,
- "CAddonInstallJob::{}: failed to install repository [{}]. It has dependencies defined",
- __func__, m_addon->ID());
- ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24088));
- return false;
+ bool notSystemAddon = std::none_of(deps.begin(), deps.end(), [](const DependencyInfo& dep) {
+ return CServiceBroker::GetAddonMgr().IsSystemAddon(dep.id);
+ });
+
+ if (notSystemAddon)
+ {
+ CLog::Log(
+ LOGERROR,
+ "CAddonInstallJob::{}: failed to install repository [{}]. It has dependencies defined",
+ __func__, m_addon->ID());
+ ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24088));
+ return false;
+ }
}
SetText(g_localizeStrings.Get(24079));
@@ -797,7 +817,13 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const RepositoryP
RepositoryPtr repoForDep;
AddonPtr dependencyToInstall;
- if (!addonRepos.FindDependency(addonID, m_addon, dependencyToInstall, repoForDep))
+ // origin of m_addon is empty at least if an addon is installed for the first time
+ // we need to override "parentRepoId" if the passed in repo is valid.
+
+ const std::string& parentRepoId =
+ m_addon->Origin().empty() && repo ? repo->ID() : m_addon->Origin();
+
+ if (!addonRepos.FindDependency(addonID, parentRepoId, dependencyToInstall, repoForDep))
{
CLog::Log(LOGERROR, "CAddonInstallJob[{}]: failed to find dependency {}", m_addon->ID(),
addonID);
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp
index f9a133474c..e8c0a3bab1 100644
--- a/xbmc/addons/AddonManager.cpp
+++ b/xbmc/addons/AddonManager.cpp
@@ -247,6 +247,28 @@ std::vector<std::shared_ptr<IAddon>> CAddonMgr::GetAvailableUpdatesOrOutdatedAdd
return result;
}
+bool CAddonMgr::GetAvailableUpdatesAndOutdatedAddons(
+ std::vector<std::shared_ptr<IAddon>>& outdated,
+ std::vector<std::shared_ptr<IAddon>>& updates) const
+{
+ CSingleLock lock(m_critSection);
+ auto start = XbmcThreads::SystemClockMillis();
+
+ std::vector<std::shared_ptr<IAddon>> installed;
+ CAddonRepos addonRepos(*this);
+
+ addonRepos.LoadAddonsFromDatabase(m_database);
+
+ GetAddonsForUpdate(installed);
+
+ addonRepos.BuildUpdateAndOutdatedList(installed, updates, outdated);
+
+ CLog::Log(LOGDEBUG, "CAddonMgr::GetAvailableUpdatesAndOutdatedAddons took %i ms",
+ XbmcThreads::SystemClockMillis() - start);
+
+ return true;
+}
+
bool CAddonMgr::HasAvailableUpdates()
{
return !GetAvailableUpdates().empty();
@@ -465,7 +487,7 @@ bool CAddonMgr::GetAddonUpdateCandidates(VECADDONS& updates) const
updates = GetAvailableUpdates();
updates.erase(
std::remove_if(updates.begin(), updates.end(),
- [this](const AddonPtr& addon) { return IsBlacklisted(addon->ID()); }),
+ [this](const AddonPtr& addon) { return !IsAutoUpdateable(addon->ID()); }),
updates.end());
return updates.empty();
}
@@ -585,9 +607,7 @@ bool CAddonMgr::FindAddons()
m_database.GetDisabled(tmpDisabled);
m_disabled = std::move(tmpDisabled);
- std::set<std::string> tmpBlacklist;
- m_database.GetBlacklisted(tmpBlacklist);
- m_updateBlacklist = std::move(tmpBlacklist);
+ m_updateRules.RefreshRulesMap(m_database);
return true;
}
@@ -660,32 +680,10 @@ void CAddonMgr::OnPostUnInstall(const std::string& id)
{
CSingleLock lock(m_critSection);
m_disabled.erase(id);
- m_updateBlacklist.erase(id);
+ RemoveAllUpdateRulesFromList(id);
m_events.Publish(AddonEvents::UnInstalled(id));
}
-bool CAddonMgr::RemoveFromUpdateBlacklist(const std::string& id)
-{
- CSingleLock lock(m_critSection);
- if (!IsBlacklisted(id))
- return true;
- return m_database.RemoveAddonFromBlacklist(id) && m_updateBlacklist.erase(id) > 0;
-}
-
-bool CAddonMgr::AddToUpdateBlacklist(const std::string& id)
-{
- CSingleLock lock(m_critSection);
- if (IsBlacklisted(id))
- return true;
- return m_database.BlacklistAddon(id) && m_updateBlacklist.insert(id).second;
-}
-
-bool CAddonMgr::IsBlacklisted(const std::string& id) const
-{
- CSingleLock lock(m_critSection);
- return m_updateBlacklist.find(id) != m_updateBlacklist.end();
-}
-
void CAddonMgr::UpdateLastUsed(const std::string& id)
{
auto time = CDateTime::GetCurrentDateTime();
@@ -764,6 +762,10 @@ bool CAddonMgr::EnableSingle(const std::string& id)
return false;
m_disabled.erase(id);
+ // If enabling a repo add-on without an origin, set its origin to its own id
+ if (addon->HasType(ADDON_REPOSITORY) && addon->Origin().empty())
+ SetAddonOrigin(id, id, false);
+
CServiceBroker::GetEventLog().Add(EventPtr(new CAddonManagementEvent(addon, 24064)));
CLog::Log(LOGDEBUG, "CAddonMgr: enabled %s", addon->ID().c_str());
@@ -807,7 +809,8 @@ bool CAddonMgr::CanAddonBeDisabled(const std::string& ID)
return false;
CSingleLock lock(m_critSection);
- if (IsSystemAddon(ID))
+ // Non-optional system add-ons can not be disabled
+ if (IsSystemAddon(ID) && !IsOptionalSystemAddon(ID))
return false;
AddonPtr localAddon;
@@ -844,19 +847,29 @@ bool CAddonMgr::IsAddonInstalled(const std::string& ID,
bool CAddonMgr::CanAddonBeInstalled(const AddonPtr& addon)
{
- return addon != nullptr && !addon->IsBroken() && !IsAddonInstalled(addon->ID());
+ return addon != nullptr && addon->LifecycleState() != AddonLifecycleState::BROKEN &&
+ !IsAddonInstalled(addon->ID());
}
bool CAddonMgr::CanUninstall(const AddonPtr& addon)
{
- return addon && CanAddonBeDisabled(addon->ID()) &&
- !StringUtils::StartsWith(addon->Path(), CSpecialProtocol::TranslatePath("special://xbmc/addons"));
+ return addon && !IsSystemAddon(addon->ID()) && CanAddonBeDisabled(addon->ID()) &&
+ !StringUtils::StartsWith(addon->Path(),
+ CSpecialProtocol::TranslatePath("special://xbmc/addons"));
}
bool CAddonMgr::IsSystemAddon(const std::string& id)
{
CSingleLock lock(m_critSection);
- return std::find(m_systemAddons.begin(), m_systemAddons.end(), id) != m_systemAddons.end();
+ return IsOptionalSystemAddon(id) ||
+ std::find(m_systemAddons.begin(), m_systemAddons.end(), id) != m_systemAddons.end();
+}
+
+bool CAddonMgr::IsOptionalSystemAddon(const std::string& id)
+{
+ CSingleLock lock(m_critSection);
+ return std::find(m_optionalSystemAddons.begin(), m_optionalSystemAddons.end(), id) !=
+ m_optionalSystemAddons.end();
}
bool CAddonMgr::LoadAddonDescription(const std::string &directory, AddonPtr &addon)
@@ -868,34 +881,29 @@ bool CAddonMgr::LoadAddonDescription(const std::string &directory, AddonPtr &add
return addon != nullptr;
}
-bool CAddonMgr::AddonsFromRepoXML(const CRepository::DirInfo& repo, const std::string& xml, VECADDONS& addons)
+bool CAddonMgr::AddUpdateRuleToList(const std::string& id, AddonUpdateRule updateRule)
{
- CXBMCTinyXML doc;
- if (!doc.Parse(xml))
- {
- CLog::Log(LOGERROR, "CAddonMgr::{}: Failed to parse addons.xml", __FUNCTION__);
- return false;
- }
+ return m_updateRules.AddUpdateRuleToList(m_database, id, updateRule);
+}
- if (doc.RootElement() == nullptr || doc.RootElement()->ValueStr() != "addons")
- {
- CLog::Log(LOGERROR, "CAddonMgr::{}: Failed to parse addons.xml. Malformed", __FUNCTION__);
- return false;
- }
+bool CAddonMgr::RemoveAllUpdateRulesFromList(const std::string& id)
+{
+ return m_updateRules.RemoveAllUpdateRulesFromList(m_database, id);
+}
- // each addon XML should have a UTF-8 declaration
- auto element = doc.RootElement()->FirstChildElement("addon");
- while (element)
- {
- auto addonInfo = CAddonInfoBuilder::Generate(element, repo);
- auto addon = CAddonBuilder::Generate(addonInfo, ADDON_UNKNOWN);
- if (addon)
- addons.push_back(std::move(addon));
+bool CAddonMgr::RemoveUpdateRuleFromList(const std::string& id, AddonUpdateRule updateRule)
+{
+ return m_updateRules.RemoveUpdateRuleFromList(m_database, id, updateRule);
+}
- element = element->NextSiblingElement("addon");
- }
+bool CAddonMgr::IsAutoUpdateable(const std::string& id) const
+{
+ return m_updateRules.IsAutoUpdateable(id);
+}
- return true;
+void CAddonMgr::PublishEventAutoUpdateStateChanged(const std::string& id)
+{
+ m_events.Publish(AddonEvents::AutoUpdateStateChanged(id));
}
bool CAddonMgr::IsCompatible(const IAddon& addon) const
@@ -1111,6 +1119,37 @@ bool CAddonMgr::SetAddonOrigin(const std::string& addonId, const std::string& re
return true;
}
+bool CAddonMgr::AddonsFromRepoXML(const CRepository::DirInfo& repo,
+ const std::string& xml,
+ std::vector<AddonInfoPtr>& addons)
+{
+ CXBMCTinyXML doc;
+ if (!doc.Parse(xml))
+ {
+ CLog::Log(LOGERROR, "CAddonMgr::{}: Failed to parse addons.xml", __func__);
+ return false;
+ }
+
+ if (doc.RootElement() == nullptr || doc.RootElement()->ValueStr() != "addons")
+ {
+ CLog::Log(LOGERROR, "CAddonMgr::{}: Failed to parse addons.xml. Malformed", __func__);
+ return false;
+ }
+
+ // each addon XML should have a UTF-8 declaration
+ auto element = doc.RootElement()->FirstChildElement("addon");
+ while (element)
+ {
+ auto addonInfo = CAddonInfoBuilder::Generate(element, repo);
+ if (addonInfo)
+ addons.emplace_back(addonInfo);
+
+ element = element->NextSiblingElement("addon");
+ }
+
+ return true;
+}
+
/*@}}}*/
} /* namespace ADDON */
diff --git a/xbmc/addons/AddonManager.h b/xbmc/addons/AddonManager.h
index c5c9f28ba6..6b5eb0cfc4 100644
--- a/xbmc/addons/AddonManager.h
+++ b/xbmc/addons/AddonManager.h
@@ -10,6 +10,7 @@
#include "Addon.h"
#include "AddonDatabase.h"
+#include "AddonUpdateRules.h"
#include "Repository.h"
#include "threads/CriticalSection.h"
#include "utils/EventStream.h"
@@ -242,12 +243,62 @@ namespace ADDON
bool CanUninstall(const AddonPtr& addon);
+ /*!
+ * @brief Checks whether an addon is a system addon
+ *
+ * @param[in] id id of the addon
+ * @return true if addon is system addon, false otherwise.
+ */
bool IsSystemAddon(const std::string& id);
- bool AddToUpdateBlacklist(const std::string& id);
- bool RemoveFromUpdateBlacklist(const std::string& id);
- bool IsBlacklisted(const std::string& id) const;
+ /*!
+ * @brief Checks whether an addon is an optional system addon
+ *
+ * @param[in] id id of the addon
+ * @return true if addon is an optional system addon, false otherwise.
+ */
+ bool IsOptionalSystemAddon(const std::string& id);
+
+ /*!
+ * @brief Addon update rules.
+ *
+ * member functions for handling and querying add-on update rules
+ *
+ * @warning This should be never used from other places outside of addon
+ * system directory.
+ *
+ */
+ /*@{{{*/
+
+ /* \brief Add a single update rule to the list for an addon
+ * \sa CAddonUpdateRules::AddUpdateRuleToList()
+ */
+ bool AddUpdateRuleToList(const std::string& id, AddonUpdateRule updateRule);
+
+ /* \brief Remove all rules from update rules list for an addon
+ * \sa CAddonUpdateRules::RemoveAllUpdateRulesFromList()
+ */
+ bool RemoveAllUpdateRulesFromList(const std::string& id);
+
+ /* \brief Remove a specific rule from update rules list for an addon
+ * \sa CAddonUpdateRules::RemoveUpdateRuleFromList()
+ */
+ bool RemoveUpdateRuleFromList(const std::string& id, AddonUpdateRule updateRule);
+
+ /* \brief Check if an addon version is auto-updateable
+ * \param id addon id to be checked
+ * \return true is addon is auto-updateable, false otherwise
+ * \sa CAddonUpdateRules::IsAutoUpdateable()
+ */
+ bool IsAutoUpdateable(const std::string& id) const;
+ /*@}}}*/
+
+ /* \brief Launches event AddonEvent::AutoUpdateStateChanged
+ * \param id addon id to pass through
+ * \sa CGUIDialogAddonInfo::OnToggleAutoUpdates()
+ */
+ void PublishEventAutoUpdateStateChanged(const std::string& id);
void UpdateLastUsed(const std::string& id);
/*! \brief Load the addon in the given path
@@ -258,15 +309,6 @@ namespace ADDON
*/
bool LoadAddonDescription(const std::string &path, AddonPtr &addon);
- /*! \brief Parse a repository XML file for addons and load their descriptors
- A repository XML is essentially a concatenated list of addon descriptors.
- \param repo The repository info.
- \param xml The XML document from repository.
- \param addons [out] returned list of addons.
- \return true if the repository XML file is parsed, false otherwise.
- */
- bool AddonsFromRepoXML(const CRepository::DirInfo& repo, const std::string& xml, VECADDONS& addons);
-
bool ServicesHasStarted() const;
/*!
@@ -363,9 +405,6 @@ namespace ADDON
*
* @warning This should be never used from other places outside of addon
* system directory.
- *
- * Currently listed call sources:
- * - @ref CAddonInstallJob::DoWork
*/
/*@{{{*/
@@ -383,11 +422,41 @@ namespace ADDON
* @param[in] isUpdate If call becomes done on already installed addon and
* update only.
* @return True if successfully done, otherwise false
+ *
+ * Currently listed call sources:
+ * - @ref CAddonInstallJob::DoWork
*/
bool SetAddonOrigin(const std::string& addonId, const std::string& repoAddonId, bool isUpdate);
+ /*!
+ * @brief Parse a repository XML file for addons and load their descriptors.
+ *
+ * A repository XML is essentially a concatenated list of addon descriptors.
+ *
+ * @param[in] repo The repository info.
+ * @param[in] xml The XML document from repository.
+ * @param[out] addons returned list of addons.
+ * @return true if the repository XML file is parsed, false otherwise.
+ *
+ * Currently listed call sources:
+ * - @ref CRepository::FetchIndex
+ */
+ bool AddonsFromRepoXML(const CRepository::DirInfo& repo,
+ const std::string& xml,
+ std::vector<AddonInfoPtr>& addons);
+
/*@}}}*/
+ /*!
+ * \brief Fetches list of outdated addons as well as available updates and
+ * stores them into separate vectors.
+ * \param[out] outdated target vector of outdated addons (that have updates available)
+ * \param[out] updates target vector of available updates (determined for installed add-ons)
+ * \return true or false
+ */
+ bool GetAvailableUpdatesAndOutdatedAddons(std::vector<std::shared_ptr<IAddon>>& outdated,
+ std::vector<std::shared_ptr<IAddon>>& updates) const;
+
private:
CAddonMgr& operator=(CAddonMgr const&) = delete;
@@ -451,10 +520,10 @@ namespace ADDON
mutable std::mutex m_installAddonsMutex;
std::map<std::string, AddonDisabledReason> m_disabled;
- std::set<std::string> m_updateBlacklist;
static std::map<TYPE, IAddonMgrCallback*> m_managers;
mutable CCriticalSection m_critSection;
CAddonDatabase m_database;
+ CAddonUpdateRules m_updateRules;
CEventSource<AddonEvent> m_events;
CBlockingEventSource<AddonEvent> m_unloadEvents;
std::set<std::string> m_systemAddons;
diff --git a/xbmc/addons/AddonRepos.cpp b/xbmc/addons/AddonRepos.cpp
index 919d304329..38bdbede4b 100644
--- a/xbmc/addons/AddonRepos.cpp
+++ b/xbmc/addons/AddonRepos.cpp
@@ -208,6 +208,24 @@ void CAddonRepos::BuildUpdateOrOutdatedList(const std::vector<std::shared_ptr<IA
}
}
+void CAddonRepos::BuildUpdateAndOutdatedList(const std::vector<std::shared_ptr<IAddon>>& installed,
+ std::vector<std::shared_ptr<IAddon>>& updates,
+ std::vector<std::shared_ptr<IAddon>>& outdated) const
+{
+ std::shared_ptr<IAddon> update;
+
+ CLog::Log(LOGDEBUG, "CAddonRepos::{}: Building combined list from installed add-ons", __func__);
+
+ for (const auto& addon : installed)
+ {
+ if (DoAddonUpdateCheck(addon, update))
+ {
+ updates.emplace_back(update);
+ outdated.emplace_back(addon);
+ }
+ }
+}
+
bool CAddonRepos::DoAddonUpdateCheck(const std::shared_ptr<IAddon>& addon,
std::shared_ptr<IAddon>& update) const
{
@@ -406,7 +424,7 @@ void CAddonRepos::GetLatestAddonVersionsFromAllRepos(
}
bool CAddonRepos::FindDependency(const std::string& dependsId,
- const std::shared_ptr<IAddon>& parent,
+ const std::string& parentRepoId,
std::shared_ptr<IAddon>& dependencyToInstall,
std::shared_ptr<CRepository>& repoForDep) const
{
@@ -434,7 +452,7 @@ bool CAddonRepos::FindDependency(const std::string& dependsId,
{
// If we didn't find an official version of this dependency
// ...we check in the origin repo of the parent
- if (!FindDependencyByParentRepo(dependsId, parent, dependencyToInstall))
+ if (!FindDependencyByParentRepo(dependsId, parentRepoId, dependencyToInstall))
return false;
}
@@ -446,9 +464,8 @@ bool CAddonRepos::FindDependency(const std::string& dependsId,
repoForDep = std::static_pointer_cast<CRepository>(tmp);
- CLog::Log(LOGDEBUG,
- "ADDONS: found dependency [{}] for install/update from repo [{}]. dependee is [{}]",
- dependencyToInstall->ID(), repoForDep->ID(), parent->ID());
+ CLog::Log(LOGDEBUG, "ADDONS: found dependency [{}] for install/update from repo [{}]",
+ dependencyToInstall->ID(), repoForDep->ID());
if (dependencyToInstall->HasType(ADDON_REPOSITORY))
{
@@ -463,10 +480,10 @@ bool CAddonRepos::FindDependency(const std::string& dependsId,
}
bool CAddonRepos::FindDependencyByParentRepo(const std::string& dependsId,
- const std::shared_ptr<IAddon>& parent,
+ const std::string& parentRepoId,
std::shared_ptr<IAddon>& dependencyToInstall) const
{
- const auto& repoEntry = m_latestVersionsByRepo.find(parent->Origin());
+ const auto& repoEntry = m_latestVersionsByRepo.find(parentRepoId);
if (repoEntry != m_latestVersionsByRepo.end())
{
if (GetLatestVersionByMap(dependsId, repoEntry->second, dependencyToInstall))
diff --git a/xbmc/addons/AddonRepos.h b/xbmc/addons/AddonRepos.h
index 4c9aae26cf..64c65279c5 100644
--- a/xbmc/addons/AddonRepos.h
+++ b/xbmc/addons/AddonRepos.h
@@ -77,6 +77,18 @@ public:
std::vector<std::shared_ptr<IAddon>>& outdated) const;
/*!
+ * \brief Build the list of available updates as well as outdated addons.
+ * Stored into two separate vectors
+ * \param installed vector of all addons installed on the system that are
+ * checked for an update
+ * \param[out] updates list of addon versions that have an update available
+ * \param[out] outdated list of addons that are outdated
+ */
+ void BuildUpdateAndOutdatedList(const std::vector<std::shared_ptr<IAddon>>& installed,
+ std::vector<std::shared_ptr<IAddon>>& updates,
+ std::vector<std::shared_ptr<IAddon>>& outdated) const;
+
+ /*!
* \brief Checks if the origin-repository of a given addon is defined as official repo
* but does not check the origin path (e.g. https://mirrors.kodi.tv ...)
* \param addon pointer to addon to be checked
@@ -134,27 +146,27 @@ public:
* If the dependency cannot be found in official versions we look in the
* installing/updating addon's (the parent's) origin repository
* \param dependsId addon id of the dependency we're looking for
- * \param parent addon that is the dependee / parent
+ * \param parentRepoId origin repository of the dependee
* \param [out] dependencyToInstall pointer to the found dependency, only use
* if function returns true
* \param [out] repoForDep the repository that dependency will install from finally
* \return true if the dependency was found, false otherwise
*/
bool FindDependency(const std::string& dependsId,
- const std::shared_ptr<IAddon>& parent,
+ const std::string& parentRepoId,
std::shared_ptr<IAddon>& dependencyToInstall,
std::shared_ptr<CRepository>& repoForDep) const;
/*!
* \brief Find a dependency addon in the repository of its parent
* \param dependsId addon id of the dependency we're looking for
- * \param parent addon that is the dependee / parent
+ * \param parentRepoId origin repository of the dependee
* \param [out] dependencyToInstall pointer to the found dependency, only use
* if function returns true
* \return true if the dependency was found, false otherwise
*/
bool FindDependencyByParentRepo(const std::string& dependsId,
- const std::shared_ptr<IAddon>& parent,
+ const std::string& parentRepoId,
std::shared_ptr<IAddon>& dependencyToInstall) const;
private:
diff --git a/xbmc/addons/AddonUpdateRules.cpp b/xbmc/addons/AddonUpdateRules.cpp
new file mode 100644
index 0000000000..e9a17e3eb6
--- /dev/null
+++ b/xbmc/addons/AddonUpdateRules.cpp
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+#include "AddonUpdateRules.h"
+
+#include "AddonDatabase.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+
+using namespace ADDON;
+
+bool CAddonUpdateRules::RefreshRulesMap(const CAddonDatabase& db)
+{
+ m_updateRules.clear();
+ db.GetAddonUpdateRules(m_updateRules);
+ return true;
+}
+
+bool CAddonUpdateRules::IsAutoUpdateable(const std::string& id) const
+{
+ CSingleLock lock(m_critSection);
+ return m_updateRules.find(id) == m_updateRules.end();
+}
+
+bool CAddonUpdateRules::IsUpdateableByRule(const std::string& id, AddonUpdateRule updateRule) const
+{
+ CSingleLock lock(m_critSection);
+ const auto& updateRulesEntry = m_updateRules.find(id);
+ return (updateRulesEntry == m_updateRules.end() ||
+ std::none_of(updateRulesEntry->second.begin(), updateRulesEntry->second.end(),
+ [updateRule](AddonUpdateRule rule) { return rule == updateRule; }));
+}
+
+bool CAddonUpdateRules::AddUpdateRuleToList(CAddonDatabase& db,
+ const std::string& id,
+ AddonUpdateRule updateRule)
+{
+ CSingleLock lock(m_critSection);
+
+ if (!IsUpdateableByRule(id, updateRule))
+ {
+ return true;
+ }
+
+ if (db.AddUpdateRuleForAddon(id, updateRule))
+ {
+ m_updateRules[id].emplace_back(updateRule);
+ return true;
+ }
+ return false;
+}
+
+bool CAddonUpdateRules::RemoveUpdateRuleFromList(CAddonDatabase& db,
+ const std::string& id,
+ AddonUpdateRule updateRule)
+{
+ return (updateRule != AddonUpdateRule::ANY && RemoveFromUpdateRuleslist(db, id, updateRule));
+}
+
+bool CAddonUpdateRules::RemoveAllUpdateRulesFromList(CAddonDatabase& db, const std::string& id)
+{
+ return RemoveFromUpdateRuleslist(db, id, AddonUpdateRule::ANY);
+}
+
+bool CAddonUpdateRules::RemoveFromUpdateRuleslist(CAddonDatabase& db,
+ const std::string& id,
+ AddonUpdateRule updateRule)
+{
+ CSingleLock lock(m_critSection);
+
+ const auto& updateRulesEntry = m_updateRules.find(id);
+ if (updateRulesEntry != m_updateRules.end())
+ {
+ bool onlySingleRule = (updateRulesEntry->second.size() == 1);
+
+ if (updateRule == AddonUpdateRule::ANY ||
+ (onlySingleRule && updateRulesEntry->second.front() == updateRule))
+ {
+ if (db.RemoveAllUpdateRulesForAddon(id))
+ {
+ m_updateRules.erase(id);
+ return true;
+ }
+ }
+ else if (!onlySingleRule)
+ {
+ const auto& position =
+ std::find(updateRulesEntry->second.begin(), updateRulesEntry->second.end(), updateRule);
+ if (position != updateRulesEntry->second.end() && db.RemoveUpdateRuleForAddon(id, updateRule))
+ {
+ updateRulesEntry->second.erase(position);
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/xbmc/addons/AddonUpdateRules.h b/xbmc/addons/AddonUpdateRules.h
new file mode 100644
index 0000000000..08af4ca592
--- /dev/null
+++ b/xbmc/addons/AddonUpdateRules.h
@@ -0,0 +1,87 @@
+/*
+ * 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 "addoninfo/AddonInfo.h"
+#include "threads/CriticalSection.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace ADDON
+{
+
+class CAddonDatabase;
+
+/**
+ * Class - CAddonUpdateRules
+ * Manages information about the updateability of addons by defining
+ * and handling certain rules.
+ */
+class CAddonUpdateRules
+{
+public:
+ /* \brief Refresh addon update rules map from the database
+ * \param db database connection
+ * \return true on success, false otherwise
+ */
+ bool RefreshRulesMap(const CAddonDatabase& db);
+
+ /* \brief Check if an addon version is auto updateable
+ * \param id addon id to be checked
+ * \return true is addon is auto updateable, false otherwise
+ */
+ bool IsAutoUpdateable(const std::string& id) const;
+
+ /* \brief Add a single rule to the update rules list for an addon
+ * \param db database connection
+ * \param id addon-id to set rule for
+ * \param the rule to set
+ * \return true on success, false otherwise
+ */
+ bool AddUpdateRuleToList(CAddonDatabase& db, const std::string& id, AddonUpdateRule updateRule);
+
+ /* \brief Remove a single rule from the update rules list for an addon
+ * \param db database connection
+ * \param id addon-id to remove rule for
+ * \param the rule to remove
+ * \return true on success, false otherwise
+ */
+ bool RemoveUpdateRuleFromList(CAddonDatabase& db,
+ const std::string& id,
+ AddonUpdateRule updateRule);
+
+ /* \brief Remove all rules from the update rules list for an addon
+ * \param db database connection
+ * \param id addon-id to remove rules for
+ * \return true on success, false otherwise
+ */
+ bool RemoveAllUpdateRulesFromList(CAddonDatabase& db, const std::string& id);
+
+private:
+ /* \brief Checks if an addon version is updateable with a specific rule
+ * \param id addon id to be checked
+ * \param updateRule the rule to check for
+ * \return true is addon is updateable by that updateRule, false otherwise
+ * \sa CAddonUpdateRules::IsAutoUpdateable()
+ */
+ bool IsUpdateableByRule(const std::string& id, AddonUpdateRule updateRule) const;
+
+ /* \brief Executor for @ref RemoveUpdateRuleFromList() and @ref RemoveAllUpdateRulesFromList()
+ */
+ bool RemoveFromUpdateRuleslist(CAddonDatabase& db,
+ const std::string& id,
+ AddonUpdateRule updateRule);
+
+ mutable CCriticalSection m_critSection;
+ std::map<std::string, std::vector<AddonUpdateRule>> m_updateRules;
+};
+
+}; /* namespace ADDON */
diff --git a/xbmc/addons/CMakeLists.txt b/xbmc/addons/CMakeLists.txt
index 018730e84f..404896399d 100644
--- a/xbmc/addons/CMakeLists.txt
+++ b/xbmc/addons/CMakeLists.txt
@@ -7,6 +7,7 @@ set(SOURCES Addon.cpp
AddonRepos.cpp
AddonStatusHandler.cpp
AddonSystemSettings.cpp
+ AddonUpdateRules.cpp
AddonVersion.cpp
AudioDecoder.cpp
AudioEncoder.cpp
@@ -42,6 +43,7 @@ set(HEADERS Addon.h
AddonRepos.h
AddonStatusHandler.h
AddonSystemSettings.h
+ AddonUpdateRules.h
AddonVersion.h
AudioDecoder.h
AudioEncoder.h
diff --git a/xbmc/addons/ContextMenus.cpp b/xbmc/addons/ContextMenus.cpp
index 2f9e4fd413..5e9d7475e7 100644
--- a/xbmc/addons/ContextMenus.cpp
+++ b/xbmc/addons/ContextMenus.cpp
@@ -13,7 +13,7 @@
#include "RepositoryUpdater.h"
#include "ServiceBroker.h"
#include "addons/gui/GUIDialogAddonSettings.h"
-
+#include "addons/gui/GUIHelpers.h"
namespace CONTEXTMENU
{
@@ -61,6 +61,10 @@ bool CEnableAddon::IsVisible(const CFileItem& item) const
bool CEnableAddon::Execute(const CFileItemPtr& item) const
{
+ // Check user want to enable if lifecycle not normal
+ if (!ADDON::GUI::CHelpers::DialogAddonLifecycleUseAsk(item->GetAddonInfo()))
+ return false;
+
return CServiceBroker::GetAddonMgr().EnableAddon(item->GetAddonInfo()->ID());
}
diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h
index 7e7d81b201..743ba9393f 100644
--- a/xbmc/addons/IAddon.h
+++ b/xbmc/addons/IAddon.h
@@ -54,7 +54,8 @@ namespace ADDON
virtual std::string Author() const =0;
virtual std::string Icon() const =0;
virtual std::string Disclaimer() const =0;
- virtual std::string Broken() const =0;
+ virtual AddonLifecycleState LifecycleState() const = 0;
+ virtual std::string LifecycleStateDescription() const = 0;
virtual CDateTime InstallDate() const =0;
virtual CDateTime LastUpdated() const =0;
virtual CDateTime LastUsed() const =0;
@@ -84,8 +85,5 @@ namespace ADDON
virtual void OnPostInstall(bool update, bool modal) =0;
virtual void OnPreUnInstall() =0;
virtual void OnPostUnInstall() =0;
-
- // Derived property
- bool IsBroken() const { return !Broken().empty(); }
};
};
diff --git a/xbmc/addons/Repository.cpp b/xbmc/addons/Repository.cpp
index f366c4f499..22fd0889e8 100644
--- a/xbmc/addons/Repository.cpp
+++ b/xbmc/addons/Repository.cpp
@@ -111,7 +111,8 @@ CRepository::CRepository(const AddonInfoPtr& addonInfo)
for (auto element : Type(ADDON_REPOSITORY)->GetElements("dir"))
{
DirInfo dir = ParseDirConfiguration(element.second);
- if (dir.version <= version)
+ if ((dir.minversion.empty() || version >= dir.minversion) &&
+ (dir.maxversion.empty() || version <= dir.maxversion))
m_dirs.push_back(std::move(dir));
}
if (!Type(ADDON_REPOSITORY)->GetValue("info").empty())
@@ -182,7 +183,9 @@ bool CRepository::FetchChecksum(const std::string& url,
return true;
}
-bool CRepository::FetchIndex(const DirInfo& repo, std::string const& digest, VECADDONS& addons) noexcept
+bool CRepository::FetchIndex(const DirInfo& repo,
+ std::string const& digest,
+ std::vector<AddonInfoPtr>& addons) noexcept
{
XFILE::CCurlFile http;
@@ -221,7 +224,7 @@ bool CRepository::FetchIndex(const DirInfo& repo, std::string const& digest, VEC
CRepository::FetchStatus CRepository::FetchIfChanged(const std::string& oldChecksum,
std::string& checksum,
- VECADDONS& addons,
+ std::vector<AddonInfoPtr>& addons,
int& recheckAfter) const
{
checksum = "";
@@ -259,7 +262,7 @@ CRepository::FetchStatus CRepository::FetchIfChanged(const std::string& oldCheck
for (const auto& dirTuple : dirChecksums)
{
- VECADDONS tmp;
+ std::vector<AddonInfoPtr> tmp;
if (!FetchIndex(std::get<0>(dirTuple), std::get<1>(dirTuple), tmp))
return STATUS_ERROR;
addons.insert(addons.end(), tmp.begin(), tmp.end());
@@ -300,7 +303,9 @@ CRepository::DirInfo CRepository::ParseDirConfiguration(const CAddonExtensions&
}
}
- dir.version = AddonVersion{configuration.GetValue("@minversion").asString()};
+ dir.minversion = AddonVersion{configuration.GetValue("@minversion").asString()};
+ dir.maxversion = AddonVersion{configuration.GetValue("@maxversion").asString()};
+
return dir;
}
@@ -321,7 +326,7 @@ bool CRepositoryUpdateJob::DoWork()
oldChecksum = "";
std::string newChecksum;
- VECADDONS addons;
+ std::vector<AddonInfoPtr> addons;
int recheckAfter;
auto status = m_repo->FetchIfChanged(oldChecksum, newChecksum, addons, recheckAfter);
diff --git a/xbmc/addons/Repository.h b/xbmc/addons/Repository.h
index 66537e5a06..2903f5f95a 100644
--- a/xbmc/addons/Repository.h
+++ b/xbmc/addons/Repository.h
@@ -23,7 +23,8 @@ namespace ADDON
public:
struct DirInfo
{
- AddonVersion version{""};
+ AddonVersion minversion{""};
+ AddonVersion maxversion{""};
std::string info;
std::string checksum;
KODI::UTILITY::CDigest::Type checksumType{KODI::UTILITY::CDigest::Type::INVALID};
@@ -45,7 +46,7 @@ namespace ADDON
FetchStatus FetchIfChanged(const std::string& oldChecksum,
std::string& checksum,
- VECADDONS& addons,
+ std::vector<AddonInfoPtr>& addons,
int& recheckAfter) const;
struct ResolveResult
@@ -59,7 +60,9 @@ namespace ADDON
static bool FetchChecksum(const std::string& url,
std::string& checksum,
int& recheckAfter) noexcept;
- static bool FetchIndex(const DirInfo& repo, std::string const& digest, VECADDONS& addons) noexcept;
+ static bool FetchIndex(const DirInfo& repo,
+ std::string const& digest,
+ std::vector<AddonInfoPtr>& addons) noexcept;
static DirInfo ParseDirConfiguration(const CAddonExtensions& configuration);
diff --git a/xbmc/addons/VFSEntry.cpp b/xbmc/addons/VFSEntry.cpp
index 2120a8785e..8ed59f8015 100644
--- a/xbmc/addons/VFSEntry.cpp
+++ b/xbmc/addons/VFSEntry.cpp
@@ -14,6 +14,30 @@
#include "utils/StringUtils.h"
#include "utils/log.h"
+#if defined(TARGET_WINDOWS)
+#ifndef S_IFLNK
+#define S_IFLNK 0120000
+#endif
+#ifndef S_IFBLK
+#define S_IFBLK 0
+#endif
+#ifndef S_IFSOCK
+#define S_IFSOCK 0
+#endif
+#ifndef S_IFREG
+#define S_IFREG _S_IFREG
+#endif
+#ifndef S_IFCHR
+#define S_IFCHR _S_IFCHR
+#endif
+#ifndef S_IFDIR
+#define S_IFDIR _S_IFDIR
+#endif
+#ifndef S_IFIFO
+#define S_IFIFO _S_IFIFO
+#endif
+#endif
+
namespace ADDON
{
@@ -249,11 +273,37 @@ bool CVFSEntry::Exists(const CURL& url)
int CVFSEntry::Stat(const CURL& url, struct __stat64* buffer)
{
+ int ret = -1;
if (!m_struct.toAddon->stat)
- return -1;
+ return ret;
CVFSURLWrapper url2(url);
- return m_struct.toAddon->stat(&m_struct, &url2.url, buffer);
+ STAT_STRUCTURE statBuffer = {};
+ ret = m_struct.toAddon->stat(&m_struct, &url2.url, &statBuffer);
+
+ buffer->st_dev = statBuffer.deviceId;
+ buffer->st_ino = statBuffer.fileSerialNumber;
+ buffer->st_size = statBuffer.size;
+ buffer->st_atime = statBuffer.accessTime;
+ buffer->st_mtime = statBuffer.modificationTime;
+ buffer->st_ctime = statBuffer.statusTime;
+ buffer->st_mode = 0;
+ if (statBuffer.isDirectory)
+ buffer->st_mode |= S_IFDIR;
+ if (statBuffer.isSymLink)
+ buffer->st_mode |= S_IFLNK;
+ if (statBuffer.isBlock)
+ buffer->st_mode |= S_IFBLK;
+ if (statBuffer.isCharacter)
+ buffer->st_mode |= S_IFCHR;
+ if (statBuffer.isFifo)
+ buffer->st_mode |= S_IFIFO;
+ if (statBuffer.isRegular)
+ buffer->st_mode |= S_IFREG;
+ if (statBuffer.isSocket)
+ buffer->st_mode |= S_IFSOCK;
+
+ return ret;
}
ssize_t CVFSEntry::Read(void* ctx, void* lpBuf, size_t uiBufSize)
@@ -261,7 +311,7 @@ ssize_t CVFSEntry::Read(void* ctx, void* lpBuf, size_t uiBufSize)
if (!m_struct.toAddon->read)
return 0;
- return m_struct.toAddon->read(&m_struct, ctx, lpBuf, uiBufSize);
+ return m_struct.toAddon->read(&m_struct, ctx, static_cast<uint8_t*>(lpBuf), uiBufSize);
}
ssize_t CVFSEntry::Write(void* ctx, const void* lpBuf, size_t uiBufSize)
@@ -269,7 +319,7 @@ ssize_t CVFSEntry::Write(void* ctx, const void* lpBuf, size_t uiBufSize)
if (!m_struct.toAddon->write)
return 0;
- return m_struct.toAddon->write(&m_struct, ctx, lpBuf, uiBufSize);
+ return m_struct.toAddon->write(&m_struct, ctx, static_cast<const uint8_t*>(lpBuf), uiBufSize);
}
int64_t CVFSEntry::Seek(void* ctx, int64_t position, int whence)
@@ -320,47 +370,59 @@ int64_t CVFSEntry::GetLength(void* ctx)
int CVFSEntry::IoControl(void* ctx, XFILE::EIoControl request, void* param)
{
- if (!m_struct.toAddon->io_control)
- return -1;
-
- VFS_IOCTRL ctrl = TranslateIOCTRLToAddon(request);
- if (ctrl == VFS_IOCTRL_INVALID)
- return -1;
-
- /*! @note @ref VFS_IOCTRL_NATIVE a call to addon to give data! */
- if (ctrl == VFS_IOCTRL_NATIVE)
+ switch (request)
{
- XFILE::SNativeIoControl* kodiData = static_cast<XFILE::SNativeIoControl*>(param);
- if (!kodiData)
- return -1;
-
- VFS_IOCTRL_NATIVE_DATA data;
- data.request = kodiData->request;
- data.param = kodiData->param;
- return m_struct.toAddon->io_control(&m_struct, ctx, ctrl, &data);
- }
+ case XFILE::EIoControl::IOCTRL_SEEK_POSSIBLE:
+ {
+ if (!m_struct.toAddon->io_control_get_seek_possible)
+ return -1;
+ return m_struct.toAddon->io_control_get_seek_possible(&m_struct, ctx) ? 1 : 0;
+ }
+ case XFILE::EIoControl::IOCTRL_CACHE_STATUS:
+ {
+ if (!m_struct.toAddon->io_control_get_cache_status)
+ return -1;
- /*! @note @ref VFS_IOCTRL_CACHE_STATUS a call to addon to become data from him! */
- if (ctrl == VFS_IOCTRL_CACHE_STATUS)
- {
- XFILE::SCacheStatus* kodiData = static_cast<XFILE::SCacheStatus*>(param);
- if (!kodiData)
- return -1;
+ XFILE::SCacheStatus* kodiData = static_cast<XFILE::SCacheStatus*>(param);
+ if (!kodiData)
+ return -1;
- VFS_IOCTRL_CACHE_STATUS_DATA data = {0};
- int ret = m_struct.toAddon->io_control(&m_struct, ctx, ctrl, &data);
- if (ret >= 0)
+ VFS_CACHE_STATUS_DATA status;
+ int ret = m_struct.toAddon->io_control_get_cache_status(&m_struct, ctx, &status) ? 0 : -1;
+ if (ret >= 0)
+ {
+ kodiData->forward = status.forward;
+ kodiData->maxrate = status.maxrate;
+ kodiData->currate = status.currate;
+ kodiData->lowspeed = status.lowspeed;
+ }
+ return ret;
+ }
+ case XFILE::EIoControl::IOCTRL_CACHE_SETRATE:
{
- kodiData->forward = data.forward;
- kodiData->maxrate = data.maxrate;
- kodiData->currate = data.currate;
- kodiData->lowspeed = data.lowspeed;
+ if (!m_struct.toAddon->io_control_set_cache_rate)
+ return -1;
+
+ unsigned int& iParam = *static_cast<unsigned int*>(param);
+ return m_struct.toAddon->io_control_set_cache_rate(&m_struct, ctx, iParam) ? 1 : 0;
}
- return ret;
+ case XFILE::EIoControl::IOCTRL_SET_RETRY:
+ {
+ if (!m_struct.toAddon->io_control_set_retry)
+ return -1;
+
+ bool& bParam = *static_cast<bool*>(param);
+ return m_struct.toAddon->io_control_set_retry(&m_struct, ctx, bParam) ? 0 : -1;
+ }
+
+ // Not by addon supported io's
+ case XFILE::EIoControl::IOCTRL_SET_CACHE:
+ case XFILE::EIoControl::IOCTRL_NATIVE:
+ default:
+ break;
}
- /*! Do the rest for IoControl, the "param" should normally "nullptr" for this. */
- return m_struct.toAddon->io_control(&m_struct, ctx, ctrl, param);
+ return -1;
}
bool CVFSEntry::Delete(const CURL& url)
@@ -501,44 +563,6 @@ bool CVFSEntry::ContainsFiles(const CURL& url, CFileItemList& items)
return true;
}
-int CVFSEntry::TranslateIOCTRLToKodi(VFS_IOCTRL ioctrl)
-{
- switch(ioctrl)
- {
- case VFS_IOCTRL_NATIVE:
- return XFILE::EIoControl::IOCTRL_NATIVE;
- case VFS_IOCTRL_SEEK_POSSIBLE:
- return XFILE::EIoControl::IOCTRL_SEEK_POSSIBLE;
- case VFS_IOCTRL_CACHE_STATUS:
- return XFILE::EIoControl::IOCTRL_CACHE_STATUS;
- case VFS_IOCTRL_CACHE_SETRATE:
- return XFILE::EIoControl::IOCTRL_CACHE_SETRATE;
- case VFS_IOCTRL_SET_RETRY:
- return XFILE::EIoControl::IOCTRL_SET_RETRY;
- default:
- return XFILE::EIoControl::IOCTRL_INVALID;
- }
-}
-
-VFS_IOCTRL CVFSEntry::TranslateIOCTRLToAddon(int ioctrl)
-{
- switch(ioctrl)
- {
- case XFILE::EIoControl::IOCTRL_NATIVE:
- return VFS_IOCTRL_NATIVE;
- case XFILE::EIoControl::IOCTRL_SEEK_POSSIBLE:
- return VFS_IOCTRL_SEEK_POSSIBLE;
- case XFILE::EIoControl::IOCTRL_CACHE_STATUS:
- return VFS_IOCTRL_CACHE_STATUS;
- case XFILE::EIoControl::IOCTRL_CACHE_SETRATE:
- return VFS_IOCTRL_CACHE_SETRATE;
- case XFILE::EIoControl::IOCTRL_SET_RETRY:
- return VFS_IOCTRL_SET_RETRY;
- default:
- return VFS_IOCTRL_INVALID;
- }
-}
-
CVFSEntryIFileWrapper::CVFSEntryIFileWrapper(VFSEntryPtr ptr) :
m_context(nullptr), m_addon(ptr)
{
diff --git a/xbmc/addons/VFSEntry.h b/xbmc/addons/VFSEntry.h
index af44378422..7fbe30fa38 100644
--- a/xbmc/addons/VFSEntry.h
+++ b/xbmc/addons/VFSEntry.h
@@ -97,18 +97,6 @@ namespace ADDON
const std::string& GetZeroconfType() const { return m_zeroconf; }
const ProtocolInfo& GetProtocolInfo() const { return m_protocolInfo; }
protected:
- /*!
- * @brief TO translate `enum XFILE::EIoControl` to/from `enum VFS_IOCTRL`.
- *
- * This is meant to interact securely between Kodi and addon.
- *
- * @note The `int` there is `enum XFILE::EIoControl`
- */
- //@{
- static int TranslateIOCTRLToKodi(VFS_IOCTRL ioctrl);
- static VFS_IOCTRL TranslateIOCTRLToAddon(int ioctrl);
- //@}
-
std::string m_protocols; //!< Protocols for VFS entry.
std::string m_extensions; //!< Extensions for VFS entry.
std::string m_zeroconf; //!< Zero conf announce string for VFS protocol.
diff --git a/xbmc/addons/addoninfo/AddonExtensions.h b/xbmc/addons/addoninfo/AddonExtensions.h
index c547ac7c34..694a9dd6e8 100644
--- a/xbmc/addons/addoninfo/AddonExtensions.h
+++ b/xbmc/addons/addoninfo/AddonExtensions.h
@@ -18,6 +18,7 @@ namespace ADDON
{
class CAddonInfoBuilder;
+class CAddonDatabaseSerializer;
struct SExtValue
{
@@ -67,6 +68,7 @@ public:
private:
friend class CAddonInfoBuilder;
+ friend class CAddonDatabaseSerializer;
std::string m_point;
EXT_VALUES m_values;
diff --git a/xbmc/addons/addoninfo/AddonInfo.h b/xbmc/addons/addoninfo/AddonInfo.h
index 4af9b70cb1..56fa86d0d9 100644
--- a/xbmc/addons/addoninfo/AddonInfo.h
+++ b/xbmc/addons/addoninfo/AddonInfo.h
@@ -47,6 +47,32 @@ enum class AddonOriginType
MANUAL = 2 /// The addon origin is a zip file, package or development build
};
+//! @brief Reasons why an addon is not updateable
+enum class AddonUpdateRule
+{
+ ANY = 0, //!< used internally, not to be explicitly set
+ USER_DISABLED_AUTO_UPDATE = 1, //!< automatic updates disabled via AddonInfo dialog
+ PIN_OLD_VERSION = 2 //!< user downgraded to an older version
+};
+
+/*!
+ * @brief Add-on state defined within addon.xml to report about the current addon
+ * lifecycle state.
+ *
+ * E.g. the add-on is broken and can no longer be used.
+ *
+ * XML examples:
+ * ~~~~~~~~~~~~~{.xml}
+ * <lifecyclestate type="broken" lang="en_GB">SOME TEXT</lifecyclestate>
+ * ~~~~~~~~~~~~~
+ */
+enum class AddonLifecycleState
+{
+ NORMAL = 0, //!< Used if an add-on has no special lifecycle state which is the default state
+ DEPRECATED = 1, //!< the add-on should be marked as deprecated but is still usable
+ BROKEN = 2, //!< the add-on should marked as broken in the repository
+};
+
struct DependencyInfo
{
std::string id;
@@ -164,7 +190,11 @@ public:
const std::vector<std::string>& Screenshots() const { return m_screenshots; }
const std::string& Disclaimer() const { return GetTranslatedText(m_disclaimer); }
const std::vector<DependencyInfo>& GetDependencies() const { return m_dependencies; }
- const std::string& Broken() const { return m_broken; }
+ AddonLifecycleState LifecycleState() const { return m_lifecycleState; }
+ const std::string& LifecycleStateDescription() const
+ {
+ return GetTranslatedText(m_lifecycleStateDescription);
+ }
const std::string& Origin() const { return m_origin; }
const InfoMap& ExtraInfo() const { return m_extrainfo; }
@@ -210,7 +240,8 @@ private:
std::vector<std::string> m_screenshots;
std::unordered_map<std::string, std::string> m_disclaimer;
std::vector<DependencyInfo> m_dependencies;
- std::string m_broken;
+ AddonLifecycleState m_lifecycleState = AddonLifecycleState::NORMAL;
+ std::unordered_map<std::string, std::string> m_lifecycleStateDescription;
CDateTime m_installDate;
CDateTime m_lastUpdated;
CDateTime m_lastUsed;
diff --git a/xbmc/addons/addoninfo/AddonInfoBuilder.cpp b/xbmc/addons/addoninfo/AddonInfoBuilder.cpp
index f36e7e57e0..75b61105f6 100644
--- a/xbmc/addons/addoninfo/AddonInfoBuilder.cpp
+++ b/xbmc/addons/addoninfo/AddonInfoBuilder.cpp
@@ -317,10 +317,32 @@ bool CAddonInfoBuilder::ParseXML(const AddonInfoPtr& addon, const TiXmlElement*
if (element && element->GetText() != nullptr)
addon->m_forum = element->GetText();
- /* Parse addon.xml "<broken">...</broken>" */
+ /* Parse addon.xml "<broken">...</broken>"
+ * NOTE: Replaced with <lifecyclestate>, available for backward compatibility */
element = child->FirstChildElement("broken");
if (element && element->GetText() != nullptr)
- addon->m_broken = element->GetText();
+ {
+ addon->m_lifecycleState = AddonLifecycleState::BROKEN;
+ addon->m_lifecycleStateDescription.emplace("en_gb", element->GetText());
+ }
+
+ /* Parse addon.xml "<lifecyclestate">...</lifecyclestate>" */
+ element = child->FirstChildElement("lifecyclestate");
+ if (element && element->GetText() != nullptr)
+ {
+ const char* lang = element->Attribute("type");
+ if (lang)
+ {
+ if (strcmp(lang, "broken") == 0)
+ addon->m_lifecycleState = AddonLifecycleState::BROKEN;
+ else if (strcmp(lang, "deprecated") == 0)
+ addon->m_lifecycleState = AddonLifecycleState::DEPRECATED;
+ else
+ addon->m_lifecycleState = AddonLifecycleState::NORMAL;
+
+ GetTextList(child, "lifecyclestate", addon->m_lifecycleStateDescription);
+ }
+ }
/* Parse addon.xml "<language">...</language>" */
element = child->FirstChildElement("language");
@@ -558,9 +580,6 @@ const char* CAddonInfoBuilder::GetPlatformLibraryName(const TiXmlElement* elemen
#if defined(TARGET_FREEBSD)
libraryName = element->Attribute("library_freebsd");
if (libraryName == nullptr)
-#elif defined(TARGET_RASPBERRY_PI)
- libraryName = element->Attribute("library_rbpi");
- if (libraryName == nullptr)
#endif
libraryName = element->Attribute("library_linux");
#elif defined(TARGET_WINDOWS_DESKTOP)
diff --git a/xbmc/addons/addoninfo/AddonInfoBuilder.h b/xbmc/addons/addoninfo/AddonInfoBuilder.h
index 722c319451..2fe4c3e974 100644
--- a/xbmc/addons/addoninfo/AddonInfoBuilder.h
+++ b/xbmc/addons/addoninfo/AddonInfoBuilder.h
@@ -44,7 +44,11 @@ public:
void SetArt(std::map<std::string, std::string> art) { m_addonInfo->m_art = std::move(art); }
void SetScreenshots(std::vector<std::string> screenshots) { m_addonInfo->m_screenshots = std::move(screenshots); }
void SetChangelog(std::string changelog) { m_addonInfo->m_changelog.insert(std::pair<std::string, std::string>("unk", std::move(changelog))); }
- void SetBroken(std::string broken) { m_addonInfo->m_broken = std::move(broken); }
+ void SetLifecycleState(AddonLifecycleState state, std::string description)
+ {
+ m_addonInfo->m_lifecycleState = state;
+ m_addonInfo->m_lifecycleStateDescription.emplace("unk", std::move(description));
+ }
void SetPath(std::string path) { m_addonInfo->m_path = std::move(path); }
void SetLibName(std::string libname) { m_addonInfo->m_libname = std::move(libname); }
void SetVersion(AddonVersion version) { m_addonInfo->m_version = std::move(version); }
@@ -53,21 +57,19 @@ public:
void SetExtrainfo(InfoMap extrainfo)
{
m_addonInfo->m_extrainfo = std::move(extrainfo);
-
- const auto& it = m_addonInfo->m_extrainfo.find("provides");
- if (it != m_addonInfo->m_extrainfo.end())
- {
- CAddonType addonType(m_addonInfo->m_mainType);
- addonType.SetProvides(it->second);
- m_addonInfo->m_types.push_back(addonType);
- }
}
- void SetType(TYPE type) { m_addonInfo->m_mainType = type; }
void SetInstallDate(const CDateTime& installDate) { m_addonInfo->m_installDate = installDate; }
void SetLastUpdated(const CDateTime& lastUpdated) { m_addonInfo->m_lastUpdated = lastUpdated; }
void SetLastUsed(const CDateTime& lastUsed) { m_addonInfo->m_lastUsed = lastUsed; }
void SetOrigin(std::string origin) { m_addonInfo->m_origin = std::move(origin); }
void SetPackageSize(uint64_t size) { m_addonInfo->m_packageSize = size; }
+ void SetExtensions(CAddonType addonType)
+ {
+ if (!addonType.GetValue("provides").empty())
+ addonType.SetProvides(addonType.GetValue("provides").asString());
+ m_addonInfo->m_types.push_back(std::move(addonType));
+ m_addonInfo->m_mainType = addonType.m_type;
+ }
const AddonInfoPtr& get() { return m_addonInfo; }
diff --git a/xbmc/addons/addoninfo/AddonType.h b/xbmc/addons/addoninfo/AddonType.h
index 34babd9e06..08f79f9189 100644
--- a/xbmc/addons/addoninfo/AddonType.h
+++ b/xbmc/addons/addoninfo/AddonType.h
@@ -72,6 +72,7 @@ typedef enum
} TYPE;
class CAddonInfoBuilder;
+class CAddonDatabaseSerializer;
class CAddonType : public CAddonExtensions
{
@@ -108,6 +109,7 @@ public:
private:
friend class CAddonInfoBuilder;
+ friend class CAddonDatabaseSerializer;
void SetProvides(const std::string& content);
diff --git a/xbmc/addons/gui/CMakeLists.txt b/xbmc/addons/gui/CMakeLists.txt
index 2199a5103b..2a9c4632b6 100644
--- a/xbmc/addons/gui/CMakeLists.txt
+++ b/xbmc/addons/gui/CMakeLists.txt
@@ -1,10 +1,12 @@
set(SOURCES GUIDialogAddonInfo.cpp
GUIDialogAddonSettings.cpp
+ GUIHelpers.cpp
GUIViewStateAddonBrowser.cpp
GUIWindowAddonBrowser.cpp)
set(HEADERS GUIDialogAddonInfo.h
GUIDialogAddonSettings.h
+ GUIHelpers.h
GUIViewStateAddonBrowser.h
GUIWindowAddonBrowser.h)
diff --git a/xbmc/addons/gui/GUIDialogAddonInfo.cpp b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
index e923547083..aaa7454823 100644
--- a/xbmc/addons/gui/GUIDialogAddonInfo.cpp
+++ b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
@@ -17,6 +17,7 @@
#include "addons/AddonManager.h"
#include "addons/AddonSystemSettings.h"
#include "addons/gui/GUIDialogAddonSettings.h"
+#include "addons/gui/GUIHelpers.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogSelect.h"
#include "dialogs/GUIDialogYesNo.h"
@@ -168,7 +169,8 @@ void CGUIDialogAddonInfo::UpdateControls()
m_localAddon && !CServiceBroker::GetAddonMgr().IsAddonDisabled(m_localAddon->ID());
bool canDisable =
isInstalled && CServiceBroker::GetAddonMgr().CanAddonBeDisabled(m_localAddon->ID());
- bool canInstall = !isInstalled && !m_item->GetAddonInfo()->IsBroken();
+ bool canInstall =
+ !isInstalled && m_item->GetAddonInfo()->LifecycleState() != AddonLifecycleState::BROKEN;
bool canUninstall = m_localAddon && CServiceBroker::GetAddonMgr().CanUninstall(m_localAddon);
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_INSTALL, canInstall || canUninstall);
@@ -192,7 +194,7 @@ void CGUIDialogAddonInfo::UpdateControls()
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_AUTOUPDATE, isInstalled && autoUpdatesOn);
SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_AUTOUPDATE,
isInstalled && autoUpdatesOn &&
- !CServiceBroker::GetAddonMgr().IsBlacklisted(m_localAddon->ID()));
+ CServiceBroker::GetAddonMgr().IsAutoUpdateable(m_localAddon->ID()));
SET_CONTROL_LABEL(CONTROL_BTN_AUTOUPDATE, 21340);
CONTROL_ENABLE_ON_CONDITION(
@@ -301,9 +303,20 @@ void CGUIDialogAddonInfo::OnUpdate()
if (i != -1)
{
Close();
- //turn auto updating off if downgrading
+ // turn auto updating off if downgrading
+
if (m_localAddon->Version() > versions[i].first)
- CServiceBroker::GetAddonMgr().AddToUpdateBlacklist(m_localAddon->ID());
+ CServiceBroker::GetAddonMgr().AddUpdateRuleToList(m_localAddon->ID(),
+ AddonUpdateRule::PIN_OLD_VERSION);
+
+ // turn auto updating on if upgrading or changing origin
+ // (but not when changing to local cache)
+
+ if ((m_localAddon->Version() < versions[i].first &&
+ m_localAddon->Origin() == versions[i].second) ||
+ (m_localAddon->Origin() != versions[i].second && versions[i].second != LOCAL_CACHE))
+ CServiceBroker::GetAddonMgr().RemoveUpdateRuleFromList(m_localAddon->ID(),
+ AddonUpdateRule::PIN_OLD_VERSION);
if (versions[i].second == LOCAL_CACHE)
CAddonInstaller::GetInstance().InstallFromZip(
@@ -323,9 +336,12 @@ void CGUIDialogAddonInfo::OnToggleAutoUpdates()
{
bool selected = msg.GetParam1() == 1;
if (selected)
- CServiceBroker::GetAddonMgr().RemoveFromUpdateBlacklist(m_localAddon->ID());
+ CServiceBroker::GetAddonMgr().RemoveAllUpdateRulesFromList(m_localAddon->ID());
else
- CServiceBroker::GetAddonMgr().AddToUpdateBlacklist(m_localAddon->ID());
+ CServiceBroker::GetAddonMgr().AddUpdateRuleToList(m_localAddon->ID(),
+ AddonUpdateRule::USER_DISABLED_AUTO_UPDATE);
+
+ CServiceBroker::GetAddonMgr().PublishEventAutoUpdateStateChanged(m_localAddon->ID());
}
}
@@ -337,7 +353,12 @@ void CGUIDialogAddonInfo::OnInstall()
if (!m_item->HasAddonInfo())
return;
- if (m_localAddon)
+ const auto& itemAddonInfo = m_item->GetAddonInfo();
+ const std::string& origin = itemAddonInfo->Origin();
+
+ if (m_localAddon && (m_localAddon->Origin() != origin) &&
+ (CAddonSystemSettings::GetInstance().GetAddonRepoUpdateMode() !=
+ AddonRepoUpdateMode::ANY_REPOSITORY))
{
const std::string& header = g_localizeStrings.Get(19098); // Warning!
const std::string text =
@@ -355,10 +376,7 @@ void CGUIDialogAddonInfo::OnInstall()
}
}
- const auto& itemAddonInfo = m_item->GetAddonInfo();
-
const std::string& addonId = itemAddonInfo->ID();
- const std::string& origin = itemAddonInfo->Origin();
const AddonVersion& version = itemAddonInfo->Version();
Close();
@@ -480,7 +498,13 @@ void CGUIDialogAddonInfo::OnEnableDisable()
CServiceBroker::GetAddonMgr().DisableAddon(m_localAddon->ID(), AddonDisabledReason::USER);
}
else
+ {
+ // Check user want to enable if lifecycle not normal
+ if (!ADDON::GUI::CHelpers::DialogAddonLifecycleUseAsk(m_localAddon))
+ return;
+
CServiceBroker::GetAddonMgr().EnableAddon(m_localAddon->ID());
+ }
UpdateControls();
}
diff --git a/xbmc/addons/gui/GUIHelpers.cpp b/xbmc/addons/gui/GUIHelpers.cpp
new file mode 100644
index 0000000000..0a44a6048f
--- /dev/null
+++ b/xbmc/addons/gui/GUIHelpers.cpp
@@ -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.
+ */
+
+#include "GUIHelpers.h"
+
+#include "dialogs/GUIDialogYesNo.h"
+#include "guilib/LocalizeStrings.h"
+
+using namespace ADDON;
+using namespace ADDON::GUI;
+
+bool CHelpers::DialogAddonLifecycleUseAsk(const std::shared_ptr<const IAddon>& addonInfo)
+{
+ int header_nr;
+ int text_nr;
+ switch (addonInfo->LifecycleState())
+ {
+ case AddonLifecycleState::BROKEN:
+ header_nr = 24164;
+ text_nr = 24165;
+ break;
+ case AddonLifecycleState::DEPRECATED:
+ header_nr = 24166;
+ text_nr = 24167;
+ break;
+ default:
+ header_nr = 0;
+ text_nr = 0;
+ break;
+ }
+ if (header_nr > 0)
+ {
+ std::string header = StringUtils::Format(g_localizeStrings.Get(header_nr), addonInfo->ID());
+ std::string text =
+ StringUtils::Format(g_localizeStrings.Get(text_nr), addonInfo->LifecycleStateDescription());
+ if (!CGUIDialogYesNo::ShowAndGetInput(header, text))
+ return false;
+ }
+
+ return true;
+}
diff --git a/xbmc/addons/gui/GUIHelpers.h b/xbmc/addons/gui/GUIHelpers.h
new file mode 100644
index 0000000000..32c290d61f
--- /dev/null
+++ b/xbmc/addons/gui/GUIHelpers.h
@@ -0,0 +1,38 @@
+/*
+ * 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 "addons/IAddon.h"
+
+namespace ADDON
+{
+namespace GUI
+{
+
+class CHelpers
+{
+public:
+ /*!
+ * @brief This shows an Yes/No dialog with information about the add-on if it is
+ * not in the normal status.
+ *
+ * This asks the user whether he really wants to use the add-on and informs with
+ * text why the other status is.
+ *
+ * @note The dialog is currently displayed for @ref AddonLifecycleState::BROKEN
+ * and @ref AddonLifecycleState::DEPRECATED.
+ *
+ * @param[in] addonInfo Information class of the add-on to be checked
+ * @return True if user activation is desired, false if not
+ */
+ static bool DialogAddonLifecycleUseAsk(const std::shared_ptr<const IAddon>& addonInfo);
+};
+
+} /* namespace GUI */
+} /* namespace ADDON */
diff --git a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
index b25bf3aa41..b80630b7bb 100644
--- a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
+++ b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
@@ -165,6 +165,16 @@ class UpdateAddons : public IRunnable
}
};
+class UpdateAllowedAddons : public IRunnable
+{
+ void Run() override
+ {
+ for (const auto& addon : CServiceBroker::GetAddonMgr().GetAvailableUpdates())
+ if (CServiceBroker::GetAddonMgr().IsAutoUpdateable(addon->ID()))
+ CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID());
+ }
+};
+
void CGUIWindowAddonBrowser::OnEvent(const ADDON::CRepositoryUpdater::RepositoryUpdated& event)
{
CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE);
@@ -220,6 +230,12 @@ bool CGUIWindowAddonBrowser::OnClick(int iItem, const std::string& player)
CGUIDialogBusy::Wait(&updater, 100, true);
return true;
}
+ if (item->GetPath() == "addons://update_allowed/")
+ {
+ UpdateAllowedAddons updater;
+ CGUIDialogBusy::Wait(&updater, 100, true);
+ return true;
+ }
if (!item->m_bIsFolder)
{
// cancel a downloading job
@@ -305,7 +321,8 @@ bool CGUIWindowAddonBrowser::GetDirectory(const std::string& strDirectory, CFile
{
for (int i = items.Size() - 1; i >= 0; i--)
{
- if (items[i]->GetAddonInfo() && items[i]->GetAddonInfo()->IsBroken())
+ if (items[i]->GetAddonInfo() &&
+ items[i]->GetAddonInfo()->LifecycleState() == AddonLifecycleState::BROKEN)
{
//check if it's installed
AddonPtr addon;
diff --git a/xbmc/addons/interfaces/Filesystem.cpp b/xbmc/addons/interfaces/Filesystem.cpp
index 3eb18dba9e..50303e0bbe 100644
--- a/xbmc/addons/interfaces/Filesystem.cpp
+++ b/xbmc/addons/interfaces/Filesystem.cpp
@@ -23,11 +23,31 @@
#include <vector>
-#ifndef S_ISDIR
-#define S_ISDIR(mode) ((((mode)) & 0170000) == (0040000))
+#if defined(TARGET_WINDOWS)
+#ifndef S_IFLNK
+#define S_IFLNK 0120000
+#endif
+#ifndef S_ISBLK
+#define S_ISBLK(m) (0)
+#endif
+#ifndef S_ISSOCK
+#define S_ISSOCK(m) (0)
#endif
#ifndef S_ISLNK
-#define S_ISLNK(mode) ((((mode)) & 0170000) == (0120000))
+#define S_ISLNK(m) ((m & S_IFLNK) != 0)
+#endif
+#ifndef S_ISCHR
+#define S_ISCHR(m) ((m & _S_IFCHR) != 0)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(m) ((m & _S_IFDIR) != 0)
+#endif
+#ifndef S_ISFIFO
+#define S_ISFIFO(m) ((m & _S_IFIFO) != 0)
+#endif
+#ifndef S_ISREG
+#define S_ISREG(m) ((m & _S_IFREG) != 0)
+#endif
#endif
using namespace kodi; // addon-dev-kit namespace
@@ -46,6 +66,7 @@ void Interface_Filesystem::Init(AddonGlobalInterface* addonInterface)
addonInterface->toKodi->kodi_filesystem->create_directory = create_directory;
addonInterface->toKodi->kodi_filesystem->directory_exists = directory_exists;
addonInterface->toKodi->kodi_filesystem->remove_directory = remove_directory;
+ addonInterface->toKodi->kodi_filesystem->remove_directory_recursive = remove_directory_recursive;
addonInterface->toKodi->kodi_filesystem->get_directory = get_directory;
addonInterface->toKodi->kodi_filesystem->free_directory = free_directory;
@@ -193,6 +214,19 @@ bool Interface_Filesystem::remove_directory(void* kodiBase, const char* path)
return CDirectory::Remove(path);
}
+bool Interface_Filesystem::remove_directory_recursive(void* kodiBase, const char* path)
+{
+ CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
+ if (addon == nullptr || path == nullptr)
+ {
+ CLog::Log(LOGERROR, "Interface_Filesystem::{} - invalid data (addon='{}', path='{}')",
+ __FUNCTION__, kodiBase, static_cast<const void*>(path));
+ return false;
+ }
+
+ return CDirectory::RemoveRecursive(path);
+}
+
static void CFileItemListToVFSDirEntries(VFSDirEntry* entries, const CFileItemList& items)
{
for (unsigned int i = 0; i < static_cast<unsigned int>(items.Size()); ++i)
@@ -297,12 +331,18 @@ bool Interface_Filesystem::stat_file(void* kodiBase,
return false;
buffer->deviceId = statBuffer.st_dev;
+ buffer->fileSerialNumber = statBuffer.st_ino;
buffer->size = statBuffer.st_size;
buffer->accessTime = statBuffer.st_atime;
buffer->modificationTime = statBuffer.st_mtime;
buffer->statusTime = statBuffer.st_ctime;
buffer->isDirectory = S_ISDIR(statBuffer.st_mode);
buffer->isSymLink = S_ISLNK(statBuffer.st_mode);
+ buffer->isBlock = S_ISBLK(statBuffer.st_mode);
+ buffer->isCharacter = S_ISCHR(statBuffer.st_mode);
+ buffer->isFifo = S_ISFIFO(statBuffer.st_mode);
+ buffer->isRegular = S_ISREG(statBuffer.st_mode);
+ buffer->isSocket = S_ISSOCK(statBuffer.st_mode);
return true;
}
diff --git a/xbmc/addons/interfaces/Filesystem.h b/xbmc/addons/interfaces/Filesystem.h
index 7e049843ed..be2d0246b9 100644
--- a/xbmc/addons/interfaces/Filesystem.h
+++ b/xbmc/addons/interfaces/Filesystem.h
@@ -41,6 +41,7 @@ struct Interface_Filesystem
static bool create_directory(void* kodiBase, const char* path);
static bool directory_exists(void* kodiBase, const char* path);
static bool remove_directory(void* kodiBase, const char* path);
+ static bool remove_directory_recursive(void* kodiBase, const char* path);
static bool get_directory(void* kodiBase,
const char* path,
const char* mask,
diff --git a/xbmc/addons/interfaces/gui/CMakeLists.txt b/xbmc/addons/interfaces/gui/CMakeLists.txt
index 0170dafd8a..3508b82fa1 100644
--- a/xbmc/addons/interfaces/gui/CMakeLists.txt
+++ b/xbmc/addons/interfaces/gui/CMakeLists.txt
@@ -1,8 +1,10 @@
-set(SOURCES General.cpp
+set(SOURCES GUITranslator.cpp
+ General.cpp
ListItem.cpp
Window.cpp)
-set(HEADERS General.h
+set(HEADERS GUITranslator.h
+ General.h
ListItem.h
Window.h)
diff --git a/xbmc/addons/interfaces/gui/GUITranslator.cpp b/xbmc/addons/interfaces/gui/GUITranslator.cpp
new file mode 100644
index 0000000000..2db26011ac
--- /dev/null
+++ b/xbmc/addons/interfaces/gui/GUITranslator.cpp
@@ -0,0 +1,969 @@
+/*
+ * 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.
+ */
+
+#include "GUITranslator.h"
+
+#include "input/actions/ActionIDs.h"
+
+using namespace ADDON;
+
+ADDON_ACTION CAddonGUITranslator::TranslateActionIdToAddon(int kodiId)
+{
+ switch (kodiId)
+ {
+ case ACTION_NONE:
+ return ADDON_ACTION_NONE;
+ case ACTION_MOVE_LEFT:
+ return ADDON_ACTION_MOVE_LEFT;
+ case ACTION_MOVE_RIGHT:
+ return ADDON_ACTION_MOVE_RIGHT;
+ case ACTION_MOVE_UP:
+ return ADDON_ACTION_MOVE_UP;
+ case ACTION_MOVE_DOWN:
+ return ADDON_ACTION_MOVE_DOWN;
+ case ACTION_PAGE_UP:
+ return ADDON_ACTION_PAGE_UP;
+ case ACTION_PAGE_DOWN:
+ return ADDON_ACTION_PAGE_DOWN;
+ case ACTION_SELECT_ITEM:
+ return ADDON_ACTION_SELECT_ITEM;
+ case ACTION_HIGHLIGHT_ITEM:
+ return ADDON_ACTION_HIGHLIGHT_ITEM;
+ case ACTION_PARENT_DIR:
+ return ADDON_ACTION_PARENT_DIR;
+ case ACTION_PREVIOUS_MENU:
+ return ADDON_ACTION_PREVIOUS_MENU;
+ case ACTION_SHOW_INFO:
+ return ADDON_ACTION_SHOW_INFO;
+ case ACTION_PAUSE:
+ return ADDON_ACTION_PAUSE;
+ case ACTION_STOP:
+ return ADDON_ACTION_STOP;
+ case ACTION_NEXT_ITEM:
+ return ADDON_ACTION_NEXT_ITEM;
+ case ACTION_PREV_ITEM:
+ return ADDON_ACTION_PREV_ITEM;
+ case ACTION_FORWARD:
+ return ADDON_ACTION_FORWARD;
+ case ACTION_REWIND:
+ return ADDON_ACTION_REWIND;
+ case ACTION_SHOW_GUI:
+ return ADDON_ACTION_SHOW_GUI;
+ case ACTION_ASPECT_RATIO:
+ return ADDON_ACTION_ASPECT_RATIO;
+ case ACTION_STEP_FORWARD:
+ return ADDON_ACTION_STEP_FORWARD;
+ case ACTION_STEP_BACK:
+ return ADDON_ACTION_STEP_BACK;
+ case ACTION_BIG_STEP_FORWARD:
+ return ADDON_ACTION_BIG_STEP_FORWARD;
+ case ACTION_BIG_STEP_BACK:
+ return ADDON_ACTION_BIG_STEP_BACK;
+ case ACTION_SHOW_OSD:
+ return ADDON_ACTION_SHOW_OSD;
+ case ACTION_SHOW_SUBTITLES:
+ return ADDON_ACTION_SHOW_SUBTITLES;
+ case ACTION_NEXT_SUBTITLE:
+ return ADDON_ACTION_NEXT_SUBTITLE;
+ case ACTION_PLAYER_DEBUG:
+ return ADDON_ACTION_PLAYER_DEBUG;
+ case ACTION_NEXT_PICTURE:
+ return ADDON_ACTION_NEXT_PICTURE;
+ case ACTION_PREV_PICTURE:
+ return ADDON_ACTION_PREV_PICTURE;
+ case ACTION_ZOOM_OUT:
+ return ADDON_ACTION_ZOOM_OUT;
+ case ACTION_ZOOM_IN:
+ return ADDON_ACTION_ZOOM_IN;
+ case ACTION_TOGGLE_SOURCE_DEST:
+ return ADDON_ACTION_TOGGLE_SOURCE_DEST;
+ case ACTION_SHOW_PLAYLIST:
+ return ADDON_ACTION_SHOW_PLAYLIST;
+ case ACTION_QUEUE_ITEM:
+ return ADDON_ACTION_QUEUE_ITEM;
+ case ACTION_REMOVE_ITEM:
+ return ADDON_ACTION_REMOVE_ITEM;
+ case ACTION_SHOW_FULLSCREEN:
+ return ADDON_ACTION_SHOW_FULLSCREEN;
+ case ACTION_ZOOM_LEVEL_NORMAL:
+ return ADDON_ACTION_ZOOM_LEVEL_NORMAL;
+ case ACTION_ZOOM_LEVEL_1:
+ return ADDON_ACTION_ZOOM_LEVEL_1;
+ case ACTION_ZOOM_LEVEL_2:
+ return ADDON_ACTION_ZOOM_LEVEL_2;
+ case ACTION_ZOOM_LEVEL_3:
+ return ADDON_ACTION_ZOOM_LEVEL_3;
+ case ACTION_ZOOM_LEVEL_4:
+ return ADDON_ACTION_ZOOM_LEVEL_4;
+ case ACTION_ZOOM_LEVEL_5:
+ return ADDON_ACTION_ZOOM_LEVEL_5;
+ case ACTION_ZOOM_LEVEL_6:
+ return ADDON_ACTION_ZOOM_LEVEL_6;
+ case ACTION_ZOOM_LEVEL_7:
+ return ADDON_ACTION_ZOOM_LEVEL_7;
+ case ACTION_ZOOM_LEVEL_8:
+ return ADDON_ACTION_ZOOM_LEVEL_8;
+ case ACTION_ZOOM_LEVEL_9:
+ return ADDON_ACTION_ZOOM_LEVEL_9;
+ case ACTION_CALIBRATE_SWAP_ARROWS:
+ return ADDON_ACTION_CALIBRATE_SWAP_ARROWS;
+ case ACTION_CALIBRATE_RESET:
+ return ADDON_ACTION_CALIBRATE_RESET;
+ case ACTION_ANALOG_MOVE:
+ return ADDON_ACTION_ANALOG_MOVE;
+ case ACTION_ROTATE_PICTURE_CW:
+ return ADDON_ACTION_ROTATE_PICTURE_CW;
+ case ACTION_ROTATE_PICTURE_CCW:
+ return ADDON_ACTION_ROTATE_PICTURE_CCW;
+ case ACTION_SUBTITLE_DELAY_MIN:
+ return ADDON_ACTION_SUBTITLE_DELAY_MIN;
+ case ACTION_SUBTITLE_DELAY_PLUS:
+ return ADDON_ACTION_SUBTITLE_DELAY_PLUS;
+ case ACTION_AUDIO_DELAY_MIN:
+ return ADDON_ACTION_AUDIO_DELAY_MIN;
+ case ACTION_AUDIO_DELAY_PLUS:
+ return ADDON_ACTION_AUDIO_DELAY_PLUS;
+ case ACTION_AUDIO_NEXT_LANGUAGE:
+ return ADDON_ACTION_AUDIO_NEXT_LANGUAGE;
+ case ACTION_CHANGE_RESOLUTION:
+ return ADDON_ACTION_CHANGE_RESOLUTION;
+ case REMOTE_0:
+ return ADDON_ACTION_REMOTE_0;
+ case REMOTE_1:
+ return ADDON_ACTION_REMOTE_1;
+ case REMOTE_2:
+ return ADDON_ACTION_REMOTE_2;
+ case REMOTE_3:
+ return ADDON_ACTION_REMOTE_3;
+ case REMOTE_4:
+ return ADDON_ACTION_REMOTE_4;
+ case REMOTE_5:
+ return ADDON_ACTION_REMOTE_5;
+ case REMOTE_6:
+ return ADDON_ACTION_REMOTE_6;
+ case REMOTE_7:
+ return ADDON_ACTION_REMOTE_7;
+ case REMOTE_8:
+ return ADDON_ACTION_REMOTE_8;
+ case REMOTE_9:
+ return ADDON_ACTION_REMOTE_9;
+ case ACTION_PLAYER_PROCESS_INFO:
+ return ADDON_ACTION_PLAYER_PROCESS_INFO;
+ case ACTION_PLAYER_PROGRAM_SELECT:
+ return ADDON_ACTION_PLAYER_PROGRAM_SELECT;
+ case ACTION_PLAYER_RESOLUTION_SELECT:
+ return ADDON_ACTION_PLAYER_RESOLUTION_SELECT;
+ case ACTION_SMALL_STEP_BACK:
+ return ADDON_ACTION_SMALL_STEP_BACK;
+ case ACTION_PLAYER_FORWARD:
+ return ADDON_ACTION_PLAYER_FORWARD;
+ case ACTION_PLAYER_REWIND:
+ return ADDON_ACTION_PLAYER_REWIND;
+ case ACTION_PLAYER_PLAY:
+ return ADDON_ACTION_PLAYER_PLAY;
+ case ACTION_DELETE_ITEM:
+ return ADDON_ACTION_DELETE_ITEM;
+ case ACTION_COPY_ITEM:
+ return ADDON_ACTION_COPY_ITEM;
+ case ACTION_MOVE_ITEM:
+ return ADDON_ACTION_MOVE_ITEM;
+ case ACTION_TAKE_SCREENSHOT:
+ return ADDON_ACTION_TAKE_SCREENSHOT;
+ case ACTION_RENAME_ITEM:
+ return ADDON_ACTION_RENAME_ITEM;
+ case ACTION_VOLUME_UP:
+ return ADDON_ACTION_VOLUME_UP;
+ case ACTION_VOLUME_DOWN:
+ return ADDON_ACTION_VOLUME_DOWN;
+ case ACTION_VOLAMP:
+ return ADDON_ACTION_VOLAMP;
+ case ACTION_MUTE:
+ return ADDON_ACTION_MUTE;
+ case ACTION_NAV_BACK:
+ return ADDON_ACTION_NAV_BACK;
+ case ACTION_VOLAMP_UP:
+ return ADDON_ACTION_VOLAMP_UP;
+ case ACTION_VOLAMP_DOWN:
+ return ADDON_ACTION_VOLAMP_DOWN;
+ case ACTION_CREATE_EPISODE_BOOKMARK:
+ return ADDON_ACTION_CREATE_EPISODE_BOOKMARK;
+ case ACTION_CREATE_BOOKMARK:
+ return ADDON_ACTION_CREATE_BOOKMARK;
+ case ACTION_CHAPTER_OR_BIG_STEP_FORWARD:
+ return ADDON_ACTION_CHAPTER_OR_BIG_STEP_FORWARD;
+ case ACTION_CHAPTER_OR_BIG_STEP_BACK:
+ return ADDON_ACTION_CHAPTER_OR_BIG_STEP_BACK;
+ case ACTION_CYCLE_SUBTITLE:
+ return ADDON_ACTION_CYCLE_SUBTITLE;
+ case ACTION_MOUSE_LEFT_CLICK:
+ return ADDON_ACTION_MOUSE_LEFT_CLICK;
+ case ACTION_MOUSE_RIGHT_CLICK:
+ return ADDON_ACTION_MOUSE_RIGHT_CLICK;
+ case ACTION_MOUSE_MIDDLE_CLICK:
+ return ADDON_ACTION_MOUSE_MIDDLE_CLICK;
+ case ACTION_MOUSE_DOUBLE_CLICK:
+ return ADDON_ACTION_MOUSE_DOUBLE_CLICK;
+ case ACTION_MOUSE_WHEEL_UP:
+ return ADDON_ACTION_MOUSE_WHEEL_UP;
+ case ACTION_MOUSE_WHEEL_DOWN:
+ return ADDON_ACTION_MOUSE_WHEEL_DOWN;
+ case ACTION_MOUSE_DRAG:
+ return ADDON_ACTION_MOUSE_DRAG;
+ case ACTION_MOUSE_MOVE:
+ return ADDON_ACTION_MOUSE_MOVE;
+ case ACTION_MOUSE_LONG_CLICK:
+ return ADDON_ACTION_MOUSE_LONG_CLICK;
+ case ACTION_MOUSE_DRAG_END:
+ return ADDON_ACTION_MOUSE_DRAG_END;
+ case ACTION_BACKSPACE:
+ return ADDON_ACTION_BACKSPACE;
+ case ACTION_SCROLL_UP:
+ return ADDON_ACTION_SCROLL_UP;
+ case ACTION_SCROLL_DOWN:
+ return ADDON_ACTION_SCROLL_DOWN;
+ case ACTION_ANALOG_FORWARD:
+ return ADDON_ACTION_ANALOG_FORWARD;
+ case ACTION_ANALOG_REWIND:
+ return ADDON_ACTION_ANALOG_REWIND;
+ case ACTION_MOVE_ITEM_UP:
+ return ADDON_ACTION_MOVE_ITEM_UP;
+ case ACTION_MOVE_ITEM_DOWN:
+ return ADDON_ACTION_MOVE_ITEM_DOWN;
+ case ACTION_CONTEXT_MENU:
+ return ADDON_ACTION_CONTEXT_MENU;
+ case ACTION_SHIFT:
+ return ADDON_ACTION_SHIFT;
+ case ACTION_SYMBOLS:
+ return ADDON_ACTION_SYMBOLS;
+ case ACTION_CURSOR_LEFT:
+ return ADDON_ACTION_CURSOR_LEFT;
+ case ACTION_CURSOR_RIGHT:
+ return ADDON_ACTION_CURSOR_RIGHT;
+ case ACTION_BUILT_IN_FUNCTION:
+ return ADDON_ACTION_BUILT_IN_FUNCTION;
+ case ACTION_SHOW_OSD_TIME:
+ return ADDON_ACTION_SHOW_OSD_TIME;
+ case ACTION_ANALOG_SEEK_FORWARD:
+ return ADDON_ACTION_ANALOG_SEEK_FORWARD;
+ case ACTION_ANALOG_SEEK_BACK:
+ return ADDON_ACTION_ANALOG_SEEK_BACK;
+ case ACTION_VIS_PRESET_SHOW:
+ return ADDON_ACTION_VIS_PRESET_SHOW;
+ case ACTION_VIS_PRESET_NEXT:
+ return ADDON_ACTION_VIS_PRESET_NEXT;
+ case ACTION_VIS_PRESET_PREV:
+ return ADDON_ACTION_VIS_PRESET_PREV;
+ case ACTION_VIS_PRESET_LOCK:
+ return ADDON_ACTION_VIS_PRESET_LOCK;
+ case ACTION_VIS_PRESET_RANDOM:
+ return ADDON_ACTION_VIS_PRESET_RANDOM;
+ case ACTION_VIS_RATE_PRESET_PLUS:
+ return ADDON_ACTION_VIS_RATE_PRESET_PLUS;
+ case ACTION_VIS_RATE_PRESET_MINUS:
+ return ADDON_ACTION_VIS_RATE_PRESET_MINUS;
+ case ACTION_SHOW_VIDEOMENU:
+ return ADDON_ACTION_SHOW_VIDEOMENU;
+ case ACTION_ENTER:
+ return ADDON_ACTION_ENTER;
+ case ACTION_INCREASE_RATING:
+ return ADDON_ACTION_INCREASE_RATING;
+ case ACTION_DECREASE_RATING:
+ return ADDON_ACTION_DECREASE_RATING;
+ case ACTION_NEXT_SCENE:
+ return ADDON_ACTION_NEXT_SCENE;
+ case ACTION_PREV_SCENE:
+ return ADDON_ACTION_PREV_SCENE;
+ case ACTION_NEXT_LETTER:
+ return ADDON_ACTION_NEXT_LETTER;
+ case ACTION_PREV_LETTER:
+ return ADDON_ACTION_PREV_LETTER;
+ case ACTION_JUMP_SMS2:
+ return ADDON_ACTION_JUMP_SMS2;
+ case ACTION_JUMP_SMS3:
+ return ADDON_ACTION_JUMP_SMS3;
+ case ACTION_JUMP_SMS4:
+ return ADDON_ACTION_JUMP_SMS4;
+ case ACTION_JUMP_SMS5:
+ return ADDON_ACTION_JUMP_SMS5;
+ case ACTION_JUMP_SMS6:
+ return ADDON_ACTION_JUMP_SMS6;
+ case ACTION_JUMP_SMS7:
+ return ADDON_ACTION_JUMP_SMS7;
+ case ACTION_JUMP_SMS8:
+ return ADDON_ACTION_JUMP_SMS8;
+ case ACTION_JUMP_SMS9:
+ return ADDON_ACTION_JUMP_SMS9;
+ case ACTION_FILTER_CLEAR:
+ return ADDON_ACTION_FILTER_CLEAR;
+ case ACTION_FILTER_SMS2:
+ return ADDON_ACTION_FILTER_SMS2;
+ case ACTION_FILTER_SMS3:
+ return ADDON_ACTION_FILTER_SMS3;
+ case ACTION_FILTER_SMS4:
+ return ADDON_ACTION_FILTER_SMS4;
+ case ACTION_FILTER_SMS5:
+ return ADDON_ACTION_FILTER_SMS5;
+ case ACTION_FILTER_SMS6:
+ return ADDON_ACTION_FILTER_SMS6;
+ case ACTION_FILTER_SMS7:
+ return ADDON_ACTION_FILTER_SMS7;
+ case ACTION_FILTER_SMS8:
+ return ADDON_ACTION_FILTER_SMS8;
+ case ACTION_FILTER_SMS9:
+ return ADDON_ACTION_FILTER_SMS9;
+ case ACTION_FIRST_PAGE:
+ return ADDON_ACTION_FIRST_PAGE;
+ case ACTION_LAST_PAGE:
+ return ADDON_ACTION_LAST_PAGE;
+ case ACTION_AUDIO_DELAY:
+ return ADDON_ACTION_AUDIO_DELAY;
+ case ACTION_SUBTITLE_DELAY:
+ return ADDON_ACTION_SUBTITLE_DELAY;
+ case ACTION_MENU:
+ return ADDON_ACTION_MENU;
+ case ACTION_SET_RATING:
+ return ADDON_ACTION_SET_RATING;
+ case ACTION_RECORD:
+ return ADDON_ACTION_RECORD;
+ case ACTION_PASTE:
+ return ADDON_ACTION_PASTE;
+ case ACTION_NEXT_CONTROL:
+ return ADDON_ACTION_NEXT_CONTROL;
+ case ACTION_PREV_CONTROL:
+ return ADDON_ACTION_PREV_CONTROL;
+ case ACTION_CHANNEL_SWITCH:
+ return ADDON_ACTION_CHANNEL_SWITCH;
+ case ACTION_CHANNEL_UP:
+ return ADDON_ACTION_CHANNEL_UP;
+ case ACTION_CHANNEL_DOWN:
+ return ADDON_ACTION_CHANNEL_DOWN;
+ case ACTION_NEXT_CHANNELGROUP:
+ return ADDON_ACTION_NEXT_CHANNELGROUP;
+ case ACTION_PREVIOUS_CHANNELGROUP:
+ return ADDON_ACTION_PREVIOUS_CHANNELGROUP;
+ case ACTION_PVR_PLAY:
+ return ADDON_ACTION_PVR_PLAY;
+ case ACTION_PVR_PLAY_TV:
+ return ADDON_ACTION_PVR_PLAY_TV;
+ case ACTION_PVR_PLAY_RADIO:
+ return ADDON_ACTION_PVR_PLAY_RADIO;
+ case ACTION_PVR_SHOW_TIMER_RULE:
+ return ADDON_ACTION_PVR_SHOW_TIMER_RULE;
+ case ACTION_CHANNEL_NUMBER_SEP:
+ return ADDON_ACTION_CHANNEL_NUMBER_SEP;
+ case ACTION_PVR_ANNOUNCE_REMINDERS:
+ return ADDON_ACTION_PVR_ANNOUNCE_REMINDERS;
+ case ACTION_TOGGLE_FULLSCREEN:
+ return ADDON_ACTION_TOGGLE_FULLSCREEN;
+ case ACTION_TOGGLE_WATCHED:
+ return ADDON_ACTION_TOGGLE_WATCHED;
+ case ACTION_SCAN_ITEM:
+ return ADDON_ACTION_SCAN_ITEM;
+ case ACTION_TOGGLE_DIGITAL_ANALOG:
+ return ADDON_ACTION_TOGGLE_DIGITAL_ANALOG;
+ case ACTION_RELOAD_KEYMAPS:
+ return ADDON_ACTION_RELOAD_KEYMAPS;
+ case ACTION_GUIPROFILE_BEGIN:
+ return ADDON_ACTION_GUIPROFILE_BEGIN;
+ case ACTION_TELETEXT_RED:
+ return ADDON_ACTION_TELETEXT_RED;
+ case ACTION_TELETEXT_GREEN:
+ return ADDON_ACTION_TELETEXT_GREEN;
+ case ACTION_TELETEXT_YELLOW:
+ return ADDON_ACTION_TELETEXT_YELLOW;
+ case ACTION_TELETEXT_BLUE:
+ return ADDON_ACTION_TELETEXT_BLUE;
+ case ACTION_INCREASE_PAR:
+ return ADDON_ACTION_INCREASE_PAR;
+ case ACTION_DECREASE_PAR:
+ return ADDON_ACTION_DECREASE_PAR;
+ case ACTION_VSHIFT_UP:
+ return ADDON_ACTION_VSHIFT_UP;
+ case ACTION_VSHIFT_DOWN:
+ return ADDON_ACTION_VSHIFT_DOWN;
+ case ACTION_PLAYER_PLAYPAUSE:
+ return ADDON_ACTION_PLAYER_PLAYPAUSE;
+ case ACTION_SUBTITLE_VSHIFT_UP:
+ return ADDON_ACTION_SUBTITLE_VSHIFT_UP;
+ case ACTION_SUBTITLE_VSHIFT_DOWN:
+ return ADDON_ACTION_SUBTITLE_VSHIFT_DOWN;
+ case ACTION_SUBTITLE_ALIGN:
+ return ADDON_ACTION_SUBTITLE_ALIGN;
+ case ACTION_FILTER:
+ return ADDON_ACTION_FILTER;
+ case ACTION_SWITCH_PLAYER:
+ return ADDON_ACTION_SWITCH_PLAYER;
+ case ACTION_STEREOMODE_NEXT:
+ return ADDON_ACTION_STEREOMODE_NEXT;
+ case ACTION_STEREOMODE_PREVIOUS:
+ return ADDON_ACTION_STEREOMODE_PREVIOUS;
+ case ACTION_STEREOMODE_TOGGLE:
+ return ADDON_ACTION_STEREOMODE_TOGGLE;
+ case ACTION_STEREOMODE_SELECT:
+ return ADDON_ACTION_STEREOMODE_SELECT;
+ case ACTION_STEREOMODE_TOMONO:
+ return ADDON_ACTION_STEREOMODE_TOMONO;
+ case ACTION_STEREOMODE_SET:
+ return ADDON_ACTION_STEREOMODE_SET;
+ case ACTION_SETTINGS_RESET:
+ return ADDON_ACTION_SETTINGS_RESET;
+ case ACTION_SETTINGS_LEVEL_CHANGE:
+ return ADDON_ACTION_SETTINGS_LEVEL_CHANGE;
+ case ACTION_TRIGGER_OSD:
+ return ADDON_ACTION_TRIGGER_OSD;
+ case ACTION_INPUT_TEXT:
+ return ADDON_ACTION_INPUT_TEXT;
+ case ACTION_VOLUME_SET:
+ return ADDON_ACTION_VOLUME_SET;
+ case ACTION_TOGGLE_COMMSKIP:
+ return ADDON_ACTION_TOGGLE_COMMSKIP;
+ case ACTION_BROWSE_SUBTITLE:
+ return ADDON_ACTION_BROWSE_SUBTITLE;
+ case ACTION_PLAYER_RESET:
+ return ADDON_ACTION_PLAYER_RESET;
+ case ACTION_TOGGLE_FONT:
+ return ADDON_ACTION_TOGGLE_FONT;
+ case ACTION_VIDEO_NEXT_STREAM:
+ return ADDON_ACTION_VIDEO_NEXT_STREAM;
+ case ACTION_QUEUE_ITEM_NEXT:
+ return ADDON_ACTION_QUEUE_ITEM_NEXT;
+ case ACTION_HDR_TOGGLE:
+ return ADDON_ACTION_HDR_TOGGLE;
+ case ACTION_VOICE_RECOGNIZE:
+ return ADDON_ACTION_VOICE_RECOGNIZE;
+ case ACTION_TOUCH_TAP:
+ return ADDON_ACTION_TOUCH_TAP;
+ case ACTION_TOUCH_TAP_TEN:
+ return ADDON_ACTION_TOUCH_TAP_TEN;
+ case ACTION_TOUCH_LONGPRESS:
+ return ADDON_ACTION_TOUCH_LONGPRESS;
+ case ACTION_TOUCH_LONGPRESS_TEN:
+ return ADDON_ACTION_TOUCH_LONGPRESS_TEN;
+ case ACTION_GESTURE_NOTIFY:
+ return ADDON_ACTION_GESTURE_NOTIFY;
+ case ACTION_GESTURE_BEGIN:
+ return ADDON_ACTION_GESTURE_BEGIN;
+ case ACTION_GESTURE_ZOOM:
+ return ADDON_ACTION_GESTURE_ZOOM;
+ case ACTION_GESTURE_ROTATE:
+ return ADDON_ACTION_GESTURE_ROTATE;
+ case ACTION_GESTURE_PAN:
+ return ADDON_ACTION_GESTURE_PAN;
+ case ACTION_GESTURE_ABORT:
+ return ADDON_ACTION_GESTURE_ABORT;
+ case ACTION_GESTURE_SWIPE_LEFT:
+ return ADDON_ACTION_GESTURE_SWIPE_LEFT;
+ case ACTION_GESTURE_SWIPE_LEFT_TEN:
+ return ADDON_ACTION_GESTURE_SWIPE_LEFT_TEN;
+ case ACTION_GESTURE_SWIPE_RIGHT:
+ return ADDON_ACTION_GESTURE_SWIPE_RIGHT;
+ case ACTION_GESTURE_SWIPE_RIGHT_TEN:
+ return ADDON_ACTION_GESTURE_SWIPE_RIGHT_TEN;
+ case ACTION_GESTURE_SWIPE_UP:
+ return ADDON_ACTION_GESTURE_SWIPE_UP;
+ case ACTION_GESTURE_SWIPE_UP_TEN:
+ return ADDON_ACTION_GESTURE_SWIPE_UP_TEN;
+ case ACTION_GESTURE_SWIPE_DOWN:
+ return ADDON_ACTION_GESTURE_SWIPE_DOWN;
+ case ACTION_GESTURE_SWIPE_DOWN_TEN:
+ return ADDON_ACTION_GESTURE_SWIPE_DOWN_TEN;
+ case ACTION_GESTURE_END:
+ return ADDON_ACTION_GESTURE_END;
+ case ACTION_ANALOG_MOVE_X_LEFT:
+ return ADDON_ACTION_ANALOG_MOVE_X_LEFT;
+ case ACTION_ANALOG_MOVE_X_RIGHT:
+ return ADDON_ACTION_ANALOG_MOVE_X_RIGHT;
+ case ACTION_ANALOG_MOVE_Y_UP:
+ return ADDON_ACTION_ANALOG_MOVE_Y_UP;
+ case ACTION_ANALOG_MOVE_Y_DOWN:
+ return ADDON_ACTION_ANALOG_MOVE_Y_DOWN;
+ case ACTION_ERROR:
+ return ADDON_ACTION_ERROR;
+ case ACTION_NOOP:
+ default:
+ return ADDON_ACTION_NOOP;
+ }
+}
+
+int CAddonGUITranslator::TranslateActionIdToKodi(ADDON_ACTION addonId)
+{
+ switch (addonId)
+ {
+ case ADDON_ACTION_NONE:
+ return ACTION_NONE;
+ case ADDON_ACTION_MOVE_LEFT:
+ return ACTION_MOVE_LEFT;
+ case ADDON_ACTION_MOVE_RIGHT:
+ return ACTION_MOVE_RIGHT;
+ case ADDON_ACTION_MOVE_UP:
+ return ACTION_MOVE_UP;
+ case ADDON_ACTION_MOVE_DOWN:
+ return ACTION_MOVE_DOWN;
+ case ADDON_ACTION_PAGE_UP:
+ return ACTION_PAGE_UP;
+ case ADDON_ACTION_PAGE_DOWN:
+ return ACTION_PAGE_DOWN;
+ case ADDON_ACTION_SELECT_ITEM:
+ return ACTION_SELECT_ITEM;
+ case ADDON_ACTION_HIGHLIGHT_ITEM:
+ return ACTION_HIGHLIGHT_ITEM;
+ case ADDON_ACTION_PARENT_DIR:
+ return ACTION_PARENT_DIR;
+ case ADDON_ACTION_PREVIOUS_MENU:
+ return ACTION_PREVIOUS_MENU;
+ case ADDON_ACTION_SHOW_INFO:
+ return ACTION_SHOW_INFO;
+ case ADDON_ACTION_PAUSE:
+ return ACTION_PAUSE;
+ case ADDON_ACTION_STOP:
+ return ACTION_STOP;
+ case ADDON_ACTION_NEXT_ITEM:
+ return ACTION_NEXT_ITEM;
+ case ADDON_ACTION_PREV_ITEM:
+ return ACTION_PREV_ITEM;
+ case ADDON_ACTION_FORWARD:
+ return ACTION_FORWARD;
+ case ADDON_ACTION_REWIND:
+ return ACTION_REWIND;
+ case ADDON_ACTION_SHOW_GUI:
+ return ACTION_SHOW_GUI;
+ case ADDON_ACTION_ASPECT_RATIO:
+ return ACTION_ASPECT_RATIO;
+ case ADDON_ACTION_STEP_FORWARD:
+ return ACTION_STEP_FORWARD;
+ case ADDON_ACTION_STEP_BACK:
+ return ACTION_STEP_BACK;
+ case ADDON_ACTION_BIG_STEP_FORWARD:
+ return ACTION_BIG_STEP_FORWARD;
+ case ADDON_ACTION_BIG_STEP_BACK:
+ return ACTION_BIG_STEP_BACK;
+ case ADDON_ACTION_SHOW_OSD:
+ return ACTION_SHOW_OSD;
+ case ADDON_ACTION_SHOW_SUBTITLES:
+ return ACTION_SHOW_SUBTITLES;
+ case ADDON_ACTION_NEXT_SUBTITLE:
+ return ACTION_NEXT_SUBTITLE;
+ case ADDON_ACTION_PLAYER_DEBUG:
+ return ACTION_PLAYER_DEBUG;
+ case ADDON_ACTION_NEXT_PICTURE:
+ return ACTION_NEXT_PICTURE;
+ case ADDON_ACTION_PREV_PICTURE:
+ return ACTION_PREV_PICTURE;
+ case ADDON_ACTION_ZOOM_OUT:
+ return ACTION_ZOOM_OUT;
+ case ADDON_ACTION_ZOOM_IN:
+ return ACTION_ZOOM_IN;
+ case ADDON_ACTION_TOGGLE_SOURCE_DEST:
+ return ACTION_TOGGLE_SOURCE_DEST;
+ case ADDON_ACTION_SHOW_PLAYLIST:
+ return ACTION_SHOW_PLAYLIST;
+ case ADDON_ACTION_QUEUE_ITEM:
+ return ACTION_QUEUE_ITEM;
+ case ADDON_ACTION_REMOVE_ITEM:
+ return ACTION_REMOVE_ITEM;
+ case ADDON_ACTION_SHOW_FULLSCREEN:
+ return ACTION_SHOW_FULLSCREEN;
+ case ADDON_ACTION_ZOOM_LEVEL_NORMAL:
+ return ACTION_ZOOM_LEVEL_NORMAL;
+ case ADDON_ACTION_ZOOM_LEVEL_1:
+ return ACTION_ZOOM_LEVEL_1;
+ case ADDON_ACTION_ZOOM_LEVEL_2:
+ return ACTION_ZOOM_LEVEL_2;
+ case ADDON_ACTION_ZOOM_LEVEL_3:
+ return ACTION_ZOOM_LEVEL_3;
+ case ADDON_ACTION_ZOOM_LEVEL_4:
+ return ACTION_ZOOM_LEVEL_4;
+ case ADDON_ACTION_ZOOM_LEVEL_5:
+ return ACTION_ZOOM_LEVEL_5;
+ case ADDON_ACTION_ZOOM_LEVEL_6:
+ return ACTION_ZOOM_LEVEL_6;
+ case ADDON_ACTION_ZOOM_LEVEL_7:
+ return ACTION_ZOOM_LEVEL_7;
+ case ADDON_ACTION_ZOOM_LEVEL_8:
+ return ACTION_ZOOM_LEVEL_8;
+ case ADDON_ACTION_ZOOM_LEVEL_9:
+ return ACTION_ZOOM_LEVEL_9;
+ case ADDON_ACTION_CALIBRATE_SWAP_ARROWS:
+ return ACTION_CALIBRATE_SWAP_ARROWS;
+ case ADDON_ACTION_CALIBRATE_RESET:
+ return ACTION_CALIBRATE_RESET;
+ case ADDON_ACTION_ANALOG_MOVE:
+ return ACTION_ANALOG_MOVE;
+ case ADDON_ACTION_ROTATE_PICTURE_CW:
+ return ACTION_ROTATE_PICTURE_CW;
+ case ADDON_ACTION_ROTATE_PICTURE_CCW:
+ return ACTION_ROTATE_PICTURE_CCW;
+ case ADDON_ACTION_SUBTITLE_DELAY_MIN:
+ return ACTION_SUBTITLE_DELAY_MIN;
+ case ADDON_ACTION_SUBTITLE_DELAY_PLUS:
+ return ACTION_SUBTITLE_DELAY_PLUS;
+ case ADDON_ACTION_AUDIO_DELAY_MIN:
+ return ACTION_AUDIO_DELAY_MIN;
+ case ADDON_ACTION_AUDIO_DELAY_PLUS:
+ return ACTION_AUDIO_DELAY_PLUS;
+ case ADDON_ACTION_AUDIO_NEXT_LANGUAGE:
+ return ACTION_AUDIO_NEXT_LANGUAGE;
+ case ADDON_ACTION_CHANGE_RESOLUTION:
+ return ACTION_CHANGE_RESOLUTION;
+ case ADDON_ACTION_REMOTE_0:
+ return REMOTE_0;
+ case ADDON_ACTION_REMOTE_1:
+ return REMOTE_1;
+ case ADDON_ACTION_REMOTE_2:
+ return REMOTE_2;
+ case ADDON_ACTION_REMOTE_3:
+ return REMOTE_3;
+ case ADDON_ACTION_REMOTE_4:
+ return REMOTE_4;
+ case ADDON_ACTION_REMOTE_5:
+ return REMOTE_5;
+ case ADDON_ACTION_REMOTE_6:
+ return REMOTE_6;
+ case ADDON_ACTION_REMOTE_7:
+ return REMOTE_7;
+ case ADDON_ACTION_REMOTE_8:
+ return REMOTE_8;
+ case ADDON_ACTION_REMOTE_9:
+ return REMOTE_9;
+ case ADDON_ACTION_PLAYER_PROCESS_INFO:
+ return ACTION_PLAYER_PROCESS_INFO;
+ case ADDON_ACTION_PLAYER_PROGRAM_SELECT:
+ return ACTION_PLAYER_PROGRAM_SELECT;
+ case ADDON_ACTION_PLAYER_RESOLUTION_SELECT:
+ return ACTION_PLAYER_RESOLUTION_SELECT;
+ case ADDON_ACTION_SMALL_STEP_BACK:
+ return ACTION_SMALL_STEP_BACK;
+ case ADDON_ACTION_PLAYER_FORWARD:
+ return ACTION_PLAYER_FORWARD;
+ case ADDON_ACTION_PLAYER_REWIND:
+ return ACTION_PLAYER_REWIND;
+ case ADDON_ACTION_PLAYER_PLAY:
+ return ACTION_PLAYER_PLAY;
+ case ADDON_ACTION_DELETE_ITEM:
+ return ACTION_DELETE_ITEM;
+ case ADDON_ACTION_COPY_ITEM:
+ return ACTION_COPY_ITEM;
+ case ADDON_ACTION_MOVE_ITEM:
+ return ACTION_MOVE_ITEM;
+ case ADDON_ACTION_TAKE_SCREENSHOT:
+ return ACTION_TAKE_SCREENSHOT;
+ case ADDON_ACTION_RENAME_ITEM:
+ return ACTION_RENAME_ITEM;
+ case ADDON_ACTION_VOLUME_UP:
+ return ACTION_VOLUME_UP;
+ case ADDON_ACTION_VOLUME_DOWN:
+ return ACTION_VOLUME_DOWN;
+ case ADDON_ACTION_VOLAMP:
+ return ACTION_VOLAMP;
+ case ADDON_ACTION_MUTE:
+ return ACTION_MUTE;
+ case ADDON_ACTION_NAV_BACK:
+ return ACTION_NAV_BACK;
+ case ADDON_ACTION_VOLAMP_UP:
+ return ACTION_VOLAMP_UP;
+ case ADDON_ACTION_VOLAMP_DOWN:
+ return ACTION_VOLAMP_DOWN;
+ case ADDON_ACTION_CREATE_EPISODE_BOOKMARK:
+ return ACTION_CREATE_EPISODE_BOOKMARK;
+ case ADDON_ACTION_CREATE_BOOKMARK:
+ return ACTION_CREATE_BOOKMARK;
+ case ADDON_ACTION_CHAPTER_OR_BIG_STEP_FORWARD:
+ return ACTION_CHAPTER_OR_BIG_STEP_FORWARD;
+ case ADDON_ACTION_CHAPTER_OR_BIG_STEP_BACK:
+ return ACTION_CHAPTER_OR_BIG_STEP_BACK;
+ case ADDON_ACTION_CYCLE_SUBTITLE:
+ return ACTION_CYCLE_SUBTITLE;
+ case ADDON_ACTION_MOUSE_LEFT_CLICK:
+ return ACTION_MOUSE_LEFT_CLICK;
+ case ADDON_ACTION_MOUSE_RIGHT_CLICK:
+ return ACTION_MOUSE_RIGHT_CLICK;
+ case ADDON_ACTION_MOUSE_MIDDLE_CLICK:
+ return ACTION_MOUSE_MIDDLE_CLICK;
+ case ADDON_ACTION_MOUSE_DOUBLE_CLICK:
+ return ACTION_MOUSE_DOUBLE_CLICK;
+ case ADDON_ACTION_MOUSE_WHEEL_UP:
+ return ACTION_MOUSE_WHEEL_UP;
+ case ADDON_ACTION_MOUSE_WHEEL_DOWN:
+ return ACTION_MOUSE_WHEEL_DOWN;
+ case ADDON_ACTION_MOUSE_DRAG:
+ return ACTION_MOUSE_DRAG;
+ case ADDON_ACTION_MOUSE_MOVE:
+ return ACTION_MOUSE_MOVE;
+ case ADDON_ACTION_MOUSE_LONG_CLICK:
+ return ACTION_MOUSE_LONG_CLICK;
+ case ADDON_ACTION_MOUSE_DRAG_END:
+ return ACTION_MOUSE_DRAG_END;
+ case ADDON_ACTION_BACKSPACE:
+ return ACTION_BACKSPACE;
+ case ADDON_ACTION_SCROLL_UP:
+ return ACTION_SCROLL_UP;
+ case ADDON_ACTION_SCROLL_DOWN:
+ return ACTION_SCROLL_DOWN;
+ case ADDON_ACTION_ANALOG_FORWARD:
+ return ACTION_ANALOG_FORWARD;
+ case ADDON_ACTION_ANALOG_REWIND:
+ return ACTION_ANALOG_REWIND;
+ case ADDON_ACTION_MOVE_ITEM_UP:
+ return ACTION_MOVE_ITEM_UP;
+ case ADDON_ACTION_MOVE_ITEM_DOWN:
+ return ACTION_MOVE_ITEM_DOWN;
+ case ADDON_ACTION_CONTEXT_MENU:
+ return ACTION_CONTEXT_MENU;
+ case ADDON_ACTION_SHIFT:
+ return ACTION_SHIFT;
+ case ADDON_ACTION_SYMBOLS:
+ return ACTION_SYMBOLS;
+ case ADDON_ACTION_CURSOR_LEFT:
+ return ACTION_CURSOR_LEFT;
+ case ADDON_ACTION_CURSOR_RIGHT:
+ return ACTION_CURSOR_RIGHT;
+ case ADDON_ACTION_BUILT_IN_FUNCTION:
+ return ACTION_BUILT_IN_FUNCTION;
+ case ADDON_ACTION_SHOW_OSD_TIME:
+ return ACTION_SHOW_OSD_TIME;
+ case ADDON_ACTION_ANALOG_SEEK_FORWARD:
+ return ACTION_ANALOG_SEEK_FORWARD;
+ case ADDON_ACTION_ANALOG_SEEK_BACK:
+ return ACTION_ANALOG_SEEK_BACK;
+ case ADDON_ACTION_VIS_PRESET_SHOW:
+ return ACTION_VIS_PRESET_SHOW;
+ case ADDON_ACTION_VIS_PRESET_NEXT:
+ return ACTION_VIS_PRESET_NEXT;
+ case ADDON_ACTION_VIS_PRESET_PREV:
+ return ACTION_VIS_PRESET_PREV;
+ case ADDON_ACTION_VIS_PRESET_LOCK:
+ return ACTION_VIS_PRESET_LOCK;
+ case ADDON_ACTION_VIS_PRESET_RANDOM:
+ return ACTION_VIS_PRESET_RANDOM;
+ case ADDON_ACTION_VIS_RATE_PRESET_PLUS:
+ return ACTION_VIS_RATE_PRESET_PLUS;
+ case ADDON_ACTION_VIS_RATE_PRESET_MINUS:
+ return ACTION_VIS_RATE_PRESET_MINUS;
+ case ADDON_ACTION_SHOW_VIDEOMENU:
+ return ACTION_SHOW_VIDEOMENU;
+ case ADDON_ACTION_ENTER:
+ return ACTION_ENTER;
+ case ADDON_ACTION_INCREASE_RATING:
+ return ACTION_INCREASE_RATING;
+ case ADDON_ACTION_DECREASE_RATING:
+ return ACTION_DECREASE_RATING;
+ case ADDON_ACTION_NEXT_SCENE:
+ return ACTION_NEXT_SCENE;
+ case ADDON_ACTION_PREV_SCENE:
+ return ACTION_PREV_SCENE;
+ case ADDON_ACTION_NEXT_LETTER:
+ return ACTION_NEXT_LETTER;
+ case ADDON_ACTION_PREV_LETTER:
+ return ACTION_PREV_LETTER;
+ case ADDON_ACTION_JUMP_SMS2:
+ return ACTION_JUMP_SMS2;
+ case ADDON_ACTION_JUMP_SMS3:
+ return ACTION_JUMP_SMS3;
+ case ADDON_ACTION_JUMP_SMS4:
+ return ACTION_JUMP_SMS4;
+ case ADDON_ACTION_JUMP_SMS5:
+ return ACTION_JUMP_SMS5;
+ case ADDON_ACTION_JUMP_SMS6:
+ return ACTION_JUMP_SMS6;
+ case ADDON_ACTION_JUMP_SMS7:
+ return ACTION_JUMP_SMS7;
+ case ADDON_ACTION_JUMP_SMS8:
+ return ACTION_JUMP_SMS8;
+ case ADDON_ACTION_JUMP_SMS9:
+ return ACTION_JUMP_SMS9;
+ case ADDON_ACTION_FILTER_CLEAR:
+ return ACTION_FILTER_CLEAR;
+ case ADDON_ACTION_FILTER_SMS2:
+ return ACTION_FILTER_SMS2;
+ case ADDON_ACTION_FILTER_SMS3:
+ return ACTION_FILTER_SMS3;
+ case ADDON_ACTION_FILTER_SMS4:
+ return ACTION_FILTER_SMS4;
+ case ADDON_ACTION_FILTER_SMS5:
+ return ACTION_FILTER_SMS5;
+ case ADDON_ACTION_FILTER_SMS6:
+ return ACTION_FILTER_SMS6;
+ case ADDON_ACTION_FILTER_SMS7:
+ return ACTION_FILTER_SMS7;
+ case ADDON_ACTION_FILTER_SMS8:
+ return ACTION_FILTER_SMS8;
+ case ADDON_ACTION_FILTER_SMS9:
+ return ACTION_FILTER_SMS9;
+ case ADDON_ACTION_FIRST_PAGE:
+ return ACTION_FIRST_PAGE;
+ case ADDON_ACTION_LAST_PAGE:
+ return ACTION_LAST_PAGE;
+ case ADDON_ACTION_AUDIO_DELAY:
+ return ACTION_AUDIO_DELAY;
+ case ADDON_ACTION_SUBTITLE_DELAY:
+ return ACTION_SUBTITLE_DELAY;
+ case ADDON_ACTION_MENU:
+ return ACTION_MENU;
+ case ADDON_ACTION_SET_RATING:
+ return ACTION_SET_RATING;
+ case ADDON_ACTION_RECORD:
+ return ACTION_RECORD;
+ case ADDON_ACTION_PASTE:
+ return ACTION_PASTE;
+ case ADDON_ACTION_NEXT_CONTROL:
+ return ACTION_NEXT_CONTROL;
+ case ADDON_ACTION_PREV_CONTROL:
+ return ACTION_PREV_CONTROL;
+ case ADDON_ACTION_CHANNEL_SWITCH:
+ return ACTION_CHANNEL_SWITCH;
+ case ADDON_ACTION_CHANNEL_UP:
+ return ACTION_CHANNEL_UP;
+ case ADDON_ACTION_CHANNEL_DOWN:
+ return ACTION_CHANNEL_DOWN;
+ case ADDON_ACTION_NEXT_CHANNELGROUP:
+ return ACTION_NEXT_CHANNELGROUP;
+ case ADDON_ACTION_PREVIOUS_CHANNELGROUP:
+ return ACTION_PREVIOUS_CHANNELGROUP;
+ case ADDON_ACTION_PVR_PLAY:
+ return ACTION_PVR_PLAY;
+ case ADDON_ACTION_PVR_PLAY_TV:
+ return ACTION_PVR_PLAY_TV;
+ case ADDON_ACTION_PVR_PLAY_RADIO:
+ return ACTION_PVR_PLAY_RADIO;
+ case ADDON_ACTION_PVR_SHOW_TIMER_RULE:
+ return ACTION_PVR_SHOW_TIMER_RULE;
+ case ADDON_ACTION_CHANNEL_NUMBER_SEP:
+ return ACTION_CHANNEL_NUMBER_SEP;
+ case ADDON_ACTION_PVR_ANNOUNCE_REMINDERS:
+ return ACTION_PVR_ANNOUNCE_REMINDERS;
+ case ADDON_ACTION_TOGGLE_FULLSCREEN:
+ return ACTION_TOGGLE_FULLSCREEN;
+ case ADDON_ACTION_TOGGLE_WATCHED:
+ return ACTION_TOGGLE_WATCHED;
+ case ADDON_ACTION_SCAN_ITEM:
+ return ACTION_SCAN_ITEM;
+ case ADDON_ACTION_TOGGLE_DIGITAL_ANALOG:
+ return ACTION_TOGGLE_DIGITAL_ANALOG;
+ case ADDON_ACTION_RELOAD_KEYMAPS:
+ return ACTION_RELOAD_KEYMAPS;
+ case ADDON_ACTION_GUIPROFILE_BEGIN:
+ return ACTION_GUIPROFILE_BEGIN;
+ case ADDON_ACTION_TELETEXT_RED:
+ return ACTION_TELETEXT_RED;
+ case ADDON_ACTION_TELETEXT_GREEN:
+ return ACTION_TELETEXT_GREEN;
+ case ADDON_ACTION_TELETEXT_YELLOW:
+ return ACTION_TELETEXT_YELLOW;
+ case ADDON_ACTION_TELETEXT_BLUE:
+ return ACTION_TELETEXT_BLUE;
+ case ADDON_ACTION_INCREASE_PAR:
+ return ACTION_INCREASE_PAR;
+ case ADDON_ACTION_DECREASE_PAR:
+ return ACTION_DECREASE_PAR;
+ case ADDON_ACTION_VSHIFT_UP:
+ return ACTION_VSHIFT_UP;
+ case ADDON_ACTION_VSHIFT_DOWN:
+ return ACTION_VSHIFT_DOWN;
+ case ADDON_ACTION_PLAYER_PLAYPAUSE:
+ return ACTION_PLAYER_PLAYPAUSE;
+ case ADDON_ACTION_SUBTITLE_VSHIFT_UP:
+ return ACTION_SUBTITLE_VSHIFT_UP;
+ case ADDON_ACTION_SUBTITLE_VSHIFT_DOWN:
+ return ACTION_SUBTITLE_VSHIFT_DOWN;
+ case ADDON_ACTION_SUBTITLE_ALIGN:
+ return ACTION_SUBTITLE_ALIGN;
+ case ADDON_ACTION_FILTER:
+ return ACTION_FILTER;
+ case ADDON_ACTION_SWITCH_PLAYER:
+ return ACTION_SWITCH_PLAYER;
+ case ADDON_ACTION_STEREOMODE_NEXT:
+ return ACTION_STEREOMODE_NEXT;
+ case ADDON_ACTION_STEREOMODE_PREVIOUS:
+ return ACTION_STEREOMODE_PREVIOUS;
+ case ADDON_ACTION_STEREOMODE_TOGGLE:
+ return ACTION_STEREOMODE_TOGGLE;
+ case ADDON_ACTION_STEREOMODE_SELECT:
+ return ACTION_STEREOMODE_SELECT;
+ case ADDON_ACTION_STEREOMODE_TOMONO:
+ return ACTION_STEREOMODE_TOMONO;
+ case ADDON_ACTION_STEREOMODE_SET:
+ return ACTION_STEREOMODE_SET;
+ case ADDON_ACTION_SETTINGS_RESET:
+ return ACTION_SETTINGS_RESET;
+ case ADDON_ACTION_SETTINGS_LEVEL_CHANGE:
+ return ACTION_SETTINGS_LEVEL_CHANGE;
+ case ADDON_ACTION_TRIGGER_OSD:
+ return ACTION_TRIGGER_OSD;
+ case ADDON_ACTION_INPUT_TEXT:
+ return ACTION_INPUT_TEXT;
+ case ADDON_ACTION_VOLUME_SET:
+ return ACTION_VOLUME_SET;
+ case ADDON_ACTION_TOGGLE_COMMSKIP:
+ return ACTION_TOGGLE_COMMSKIP;
+ case ADDON_ACTION_BROWSE_SUBTITLE:
+ return ACTION_BROWSE_SUBTITLE;
+ case ADDON_ACTION_PLAYER_RESET:
+ return ACTION_PLAYER_RESET;
+ case ADDON_ACTION_TOGGLE_FONT:
+ return ACTION_TOGGLE_FONT;
+ case ADDON_ACTION_VIDEO_NEXT_STREAM:
+ return ACTION_VIDEO_NEXT_STREAM;
+ case ADDON_ACTION_QUEUE_ITEM_NEXT:
+ return ACTION_QUEUE_ITEM_NEXT;
+ case ADDON_ACTION_HDR_TOGGLE:
+ return ACTION_HDR_TOGGLE;
+ case ADDON_ACTION_VOICE_RECOGNIZE:
+ return ACTION_VOICE_RECOGNIZE;
+ case ADDON_ACTION_TOUCH_TAP:
+ return ACTION_TOUCH_TAP;
+ case ADDON_ACTION_TOUCH_TAP_TEN:
+ return ACTION_TOUCH_TAP_TEN;
+ case ADDON_ACTION_TOUCH_LONGPRESS:
+ return ACTION_TOUCH_LONGPRESS;
+ case ADDON_ACTION_TOUCH_LONGPRESS_TEN:
+ return ACTION_TOUCH_LONGPRESS_TEN;
+ case ADDON_ACTION_GESTURE_NOTIFY:
+ return ACTION_GESTURE_NOTIFY;
+ case ADDON_ACTION_GESTURE_BEGIN:
+ return ACTION_GESTURE_BEGIN;
+ case ADDON_ACTION_GESTURE_ZOOM:
+ return ACTION_GESTURE_ZOOM;
+ case ADDON_ACTION_GESTURE_ROTATE:
+ return ACTION_GESTURE_ROTATE;
+ case ADDON_ACTION_GESTURE_PAN:
+ return ACTION_GESTURE_PAN;
+ case ADDON_ACTION_GESTURE_ABORT:
+ return ACTION_GESTURE_ABORT;
+ case ADDON_ACTION_GESTURE_SWIPE_LEFT:
+ return ACTION_GESTURE_SWIPE_LEFT;
+ case ADDON_ACTION_GESTURE_SWIPE_LEFT_TEN:
+ return ACTION_GESTURE_SWIPE_LEFT_TEN;
+ case ADDON_ACTION_GESTURE_SWIPE_RIGHT:
+ return ACTION_GESTURE_SWIPE_RIGHT;
+ case ADDON_ACTION_GESTURE_SWIPE_RIGHT_TEN:
+ return ACTION_GESTURE_SWIPE_RIGHT_TEN;
+ case ADDON_ACTION_GESTURE_SWIPE_UP:
+ return ACTION_GESTURE_SWIPE_UP;
+ case ADDON_ACTION_GESTURE_SWIPE_UP_TEN:
+ return ACTION_GESTURE_SWIPE_UP_TEN;
+ case ADDON_ACTION_GESTURE_SWIPE_DOWN:
+ return ACTION_GESTURE_SWIPE_DOWN;
+ case ADDON_ACTION_GESTURE_SWIPE_DOWN_TEN:
+ return ACTION_GESTURE_SWIPE_DOWN_TEN;
+ case ADDON_ACTION_GESTURE_END:
+ return ACTION_GESTURE_END;
+ case ADDON_ACTION_ANALOG_MOVE_X_LEFT:
+ return ACTION_ANALOG_MOVE_X_LEFT;
+ case ADDON_ACTION_ANALOG_MOVE_X_RIGHT:
+ return ACTION_ANALOG_MOVE_X_RIGHT;
+ case ADDON_ACTION_ANALOG_MOVE_Y_UP:
+ return ACTION_ANALOG_MOVE_Y_UP;
+ case ADDON_ACTION_ANALOG_MOVE_Y_DOWN:
+ return ACTION_ANALOG_MOVE_Y_DOWN;
+ case ADDON_ACTION_ERROR:
+ return ACTION_ERROR;
+ case ADDON_ACTION_NOOP:
+ default:
+ return ACTION_NOOP;
+ }
+}
diff --git a/xbmc/addons/interfaces/gui/GUITranslator.h b/xbmc/addons/interfaces/gui/GUITranslator.h
new file mode 100644
index 0000000000..8bd6b5c1ef
--- /dev/null
+++ b/xbmc/addons/interfaces/gui/GUITranslator.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.
+ */
+
+#pragma once
+
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/input/action_ids.h"
+
+namespace ADDON
+{
+
+/*!
+ * \brief Translates data types from GUI API to the corresponding format in Kodi.
+ *
+ * This class is stateless.
+ */
+class CAddonGUITranslator
+{
+ CAddonGUITranslator() = delete;
+
+public:
+ /*!
+ * \brief Translate Kodi's action id's to addon
+ * \param kodiId Kodi's action identifier
+ * \return Addon action identifier
+ */
+ static ADDON_ACTION TranslateActionIdToAddon(int kodiId);
+
+ /*!
+ * \brief Translate addon's action id's to Kodi
+ * \param addonId Addon's action identifier
+ * \return Kodi action identifier
+ */
+ static int TranslateActionIdToKodi(ADDON_ACTION addonId);
+};
+
+} /* namespace ADDON */
diff --git a/xbmc/addons/interfaces/gui/General.cpp b/xbmc/addons/interfaces/gui/General.cpp
index 9c955f6b5c..f51b12a11f 100644
--- a/xbmc/addons/interfaces/gui/General.cpp
+++ b/xbmc/addons/interfaces/gui/General.cpp
@@ -39,23 +39,13 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-using namespace kodi; // addon-dev-kit namespace
-using namespace kodi::gui; // addon-dev-kit namespace
-
namespace ADDON
{
int Interface_GUIGeneral::m_iAddonGUILockRef = 0;
-};
-
-extern "C"
-{
-
-namespace ADDON
-{
void Interface_GUIGeneral::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui = static_cast<AddonToKodiFuncTable_kodi_gui*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui)));
+ addonInterface->toKodi->kodi_gui = new AddonToKodiFuncTable_kodi_gui();
Interface_GUIControlButton::Init(addonInterface);
Interface_GUIControlEdit::Init(addonInterface);
@@ -82,14 +72,15 @@ void Interface_GUIGeneral::Init(AddonGlobalInterface* addonInterface)
Interface_GUIListItem::Init(addonInterface);
Interface_GUIWindow::Init(addonInterface);
- addonInterface->toKodi->kodi_gui->general = static_cast<AddonToKodiFuncTable_kodi_gui_general*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_general)));
+ addonInterface->toKodi->kodi_gui->general = new AddonToKodiFuncTable_kodi_gui_general();
addonInterface->toKodi->kodi_gui->general->lock = lock;
addonInterface->toKodi->kodi_gui->general->unlock = unlock;
addonInterface->toKodi->kodi_gui->general->get_screen_height = get_screen_height;
addonInterface->toKodi->kodi_gui->general->get_screen_width = get_screen_width;
addonInterface->toKodi->kodi_gui->general->get_video_resolution = get_video_resolution;
- addonInterface->toKodi->kodi_gui->general->get_current_window_dialog_id = get_current_window_dialog_id;
+ addonInterface->toKodi->kodi_gui->general->get_current_window_dialog_id =
+ get_current_window_dialog_id;
addonInterface->toKodi->kodi_gui->general->get_current_window_id = get_current_window_id;
addonInterface->toKodi->kodi_gui->general->get_hw_context = get_hw_context;
}
@@ -124,8 +115,8 @@ void Interface_GUIGeneral::DeInit(AddonGlobalInterface* addonInterface)
Interface_GUIListItem::DeInit(addonInterface);
Interface_GUIWindow::DeInit(addonInterface);
- free(addonInterface->toKodi->kodi_gui->general);
- free(addonInterface->toKodi->kodi_gui);
+ delete addonInterface->toKodi->kodi_gui->general;
+ delete addonInterface->toKodi->kodi_gui;
addonInterface->toKodi->kodi_gui = nullptr;
}
}
@@ -150,36 +141,36 @@ void Interface_GUIGeneral::unlock()
//@}
//@{
-int Interface_GUIGeneral::get_screen_height(void* kodiBase)
+int Interface_GUIGeneral::get_screen_height(KODI_HANDLE kodiBase)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "kodi::gui::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "kodi::gui::{} - invalid data", __func__);
return -1;
}
return CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight();
}
-int Interface_GUIGeneral::get_screen_width(void* kodiBase)
+int Interface_GUIGeneral::get_screen_width(KODI_HANDLE kodiBase)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "kodi::gui::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "kodi::gui::{} - invalid data", __func__);
return -1;
}
return CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth();
}
-int Interface_GUIGeneral::get_video_resolution(void* kodiBase)
+int Interface_GUIGeneral::get_video_resolution(KODI_HANDLE kodiBase)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "kodi::gui::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "kodi::gui::{} - invalid data", __func__);
return -1;
}
@@ -188,12 +179,12 @@ int Interface_GUIGeneral::get_video_resolution(void* kodiBase)
//@}
//@{
-int Interface_GUIGeneral::get_current_window_dialog_id(void* kodiBase)
+int Interface_GUIGeneral::get_current_window_dialog_id(KODI_HANDLE kodiBase)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "kodi::gui::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "kodi::gui::{} - invalid data", __func__);
return -1;
}
@@ -201,12 +192,12 @@ int Interface_GUIGeneral::get_current_window_dialog_id(void* kodiBase)
return CServiceBroker::GetGUI()->GetWindowManager().GetTopmostModalDialog();
}
-int Interface_GUIGeneral::get_current_window_id(void* kodiBase)
+int Interface_GUIGeneral::get_current_window_id(KODI_HANDLE kodiBase)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "kodi::gui::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "kodi::gui::{} - invalid data", __func__);
return -1;
}
@@ -214,7 +205,7 @@ int Interface_GUIGeneral::get_current_window_id(void* kodiBase)
return CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow();
}
-void* Interface_GUIGeneral::get_hw_context(void* kodiBase)
+ADDON_HARDWARE_CONTEXT Interface_GUIGeneral::get_hw_context(KODI_HANDLE kodiBase)
{
return CServiceBroker::GetWinSystem()->GetHWContext();
}
@@ -222,4 +213,3 @@ void* Interface_GUIGeneral::get_hw_context(void* kodiBase)
//@}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/General.h b/xbmc/addons/interfaces/gui/General.h
index ea633d5494..4ef9328c38 100644
--- a/xbmc/addons/interfaces/gui/General.h
+++ b/xbmc/addons/interfaces/gui/General.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/general.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -43,17 +45,17 @@ namespace ADDON
static void lock();
static void unlock();
- static int get_screen_height(void* kodiBase);
- static int get_screen_width(void* kodiBase);
- static int get_video_resolution(void* kodiBase);
- static int get_current_window_dialog_id(void* kodiBase);
- static int get_current_window_id(void* kodiBase);
- static void* get_hw_context(void* kodiBase);
+ static int get_screen_height(KODI_HANDLE kodiBase);
+ static int get_screen_width(KODI_HANDLE kodiBase);
+ static int get_video_resolution(KODI_HANDLE kodiBase);
+ static int get_current_window_dialog_id(KODI_HANDLE kodiBase);
+ static int get_current_window_id(KODI_HANDLE kodiBase);
+ static ADDON_HARDWARE_CONTEXT get_hw_context(KODI_HANDLE kodiBase);
//@}
private:
static int m_iAddonGUILockRef;
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/ListItem.cpp b/xbmc/addons/interfaces/gui/ListItem.cpp
index 6a243c4f6f..c91e451f48 100644
--- a/xbmc/addons/interfaces/gui/ListItem.cpp
+++ b/xbmc/addons/interfaces/gui/ListItem.cpp
@@ -16,17 +16,12 @@
#include "utils/Variant.h"
#include "utils/log.h"
-using namespace kodi; // addon-dev-kit namespace
-using namespace kodi::gui; // addon-dev-kit namespace
-
-extern "C"
-{
namespace ADDON
{
void Interface_GUIListItem::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->listItem = static_cast<AddonToKodiFuncTable_kodi_gui_listItem*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_listItem)));
+ addonInterface->toKodi->kodi_gui->listItem = new AddonToKodiFuncTable_kodi_gui_listItem();
addonInterface->toKodi->kodi_gui->listItem->create = create;
addonInterface->toKodi->kodi_gui->listItem->destroy = destroy;
@@ -46,15 +41,18 @@ void Interface_GUIListItem::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIListItem::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->listItem);
+ delete addonInterface->toKodi->kodi_gui->listItem;
}
-void* Interface_GUIListItem::create(void* kodiBase, const char* label, const char* label2, const char* icon_image, const char* path)
+KODI_GUI_LISTITEM_HANDLE Interface_GUIListItem::create(KODI_HANDLE kodiBase,
+ const char* label,
+ const char* label2,
+ const char* path)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "ADDON::Interface_GUIListItem::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "ADDON::Interface_GUIListItem::{} - invalid data", __func__);
return nullptr;
}
@@ -63,20 +61,18 @@ void* Interface_GUIListItem::create(void* kodiBase, const char* label, const cha
item->get()->SetLabel(label);
if (label2)
item->get()->SetLabel2(label2);
- if (icon_image)
- item->get()->SetArt("icon", icon_image);
if (path)
item->get()->SetPath(path);
return item;
}
-void Interface_GUIListItem::destroy(void* kodiBase, void* handle)
+void Interface_GUIListItem::destroy(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "ADDON::Interface_GUIListItem::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "ADDON::Interface_GUIListItem::{} - invalid data", __func__);
return;
}
@@ -85,23 +81,23 @@ void Interface_GUIListItem::destroy(void* kodiBase, void* handle)
delete item;
}
-char* Interface_GUIListItem::get_label(void* kodiBase, void* handle)
+char* Interface_GUIListItem::get_label(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p') on "
- "addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return nullptr;
}
@@ -112,23 +108,26 @@ char* Interface_GUIListItem::get_label(void* kodiBase, void* handle)
return ret;
}
-void Interface_GUIListItem::set_label(void* kodiBase, void* handle, const char *label)
+void Interface_GUIListItem::set_label(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item || !label)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return;
}
@@ -137,23 +136,23 @@ void Interface_GUIListItem::set_label(void* kodiBase, void* handle, const char *
Interface_GUIGeneral::unlock();
}
-char* Interface_GUIListItem::get_label2(void* kodiBase, void* handle)
+char* Interface_GUIListItem::get_label2(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p') on "
- "addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return nullptr;
}
@@ -164,23 +163,26 @@ char* Interface_GUIListItem::get_label2(void* kodiBase, void* handle)
return ret;
}
-void Interface_GUIListItem::set_label2(void* kodiBase, void* handle, const char *label)
+void Interface_GUIListItem::set_label2(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item || !label)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return;
}
@@ -189,23 +191,26 @@ void Interface_GUIListItem::set_label2(void* kodiBase, void* handle, const char
Interface_GUIGeneral::unlock();
}
-char* Interface_GUIListItem::get_art(void* kodiBase, void* handle, const char* type)
+char* Interface_GUIListItem::get_art(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* type)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item || !type)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', type='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, type, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', type='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(type),
+ addon ? addon->ID() : "unknown");
return nullptr;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return nullptr;
}
@@ -216,23 +221,27 @@ char* Interface_GUIListItem::get_art(void* kodiBase, void* handle, const char* t
return ret;
}
-void Interface_GUIListItem::set_art(void* kodiBase, void* handle, const char* type, const char* label)
+void Interface_GUIListItem::set_art(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* type,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item || !type || !label)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p', type= "
- "'%p', label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, type, label, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}', type= "
+ "'{}', label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(type),
+ static_cast<const void*>(label), addon ? addon->ID() : "unknown");
return;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return;
}
@@ -241,23 +250,23 @@ void Interface_GUIListItem::set_art(void* kodiBase, void* handle, const char* ty
Interface_GUIGeneral::unlock();
}
-char* Interface_GUIListItem::get_path(void* kodiBase, void* handle)
+char* Interface_GUIListItem::get_path(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p') on "
- "addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return nullptr;
}
@@ -269,23 +278,26 @@ char* Interface_GUIListItem::get_path(void* kodiBase, void* handle)
}
-void Interface_GUIListItem::set_path(void* kodiBase, void* handle, const char* path)
+void Interface_GUIListItem::set_path(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* path)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item || !path)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', path='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, path, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', path='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(path),
+ addon ? addon->ID() : "unknown");
return;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return;
}
@@ -294,23 +306,27 @@ void Interface_GUIListItem::set_path(void* kodiBase, void* handle, const char* p
Interface_GUIGeneral::unlock();
}
-void Interface_GUIListItem::set_property(void* kodiBase, void* handle, const char* key, const char* value)
+void Interface_GUIListItem::set_property(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* key,
+ const char* value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item || !key || !value)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p', value='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, value, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}', value='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ static_cast<const void*>(value), addon ? addon->ID() : "unknown");
return;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return;
}
@@ -322,23 +338,26 @@ void Interface_GUIListItem::set_property(void* kodiBase, void* handle, const cha
Interface_GUIGeneral::unlock();
}
-char* Interface_GUIListItem::get_property(void* kodiBase, void* handle, const char* key)
+char* Interface_GUIListItem::get_property(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* key)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return nullptr;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return nullptr;
}
@@ -352,23 +371,25 @@ char* Interface_GUIListItem::get_property(void* kodiBase, void* handle, const ch
return ret;
}
-void Interface_GUIListItem::select(void* kodiBase, void* handle, bool select)
+void Interface_GUIListItem::select(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ bool select)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p') on "
- "addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return;
}
@@ -377,23 +398,23 @@ void Interface_GUIListItem::select(void* kodiBase, void* handle, bool select)
Interface_GUIGeneral::unlock();
}
-bool Interface_GUIListItem::is_selected(void* kodiBase, void* handle)
+bool Interface_GUIListItem::is_selected(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CFileItemPtr* item = static_cast<CFileItemPtr*>(handle);
if (!addon || !item)
{
CLog::Log(LOGERROR,
- "Interface_GUIListItem::%s - invalid handler data (kodiBase='%p', handle='%p') on "
- "addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIListItem::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return false;
}
if (item->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIListItem::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIListItem::{} - empty list item called on addon '{}'",
+ __func__, addon->ID());
return false;
}
@@ -405,4 +426,3 @@ bool Interface_GUIListItem::is_selected(void* kodiBase, void* handle)
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/ListItem.h b/xbmc/addons/interfaces/gui/ListItem.h
index e3fa529b93..70e5c6a95e 100644
--- a/xbmc/addons/interfaces/gui/ListItem.h
+++ b/xbmc/addons/interfaces/gui/ListItem.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/list_item.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,22 +42,35 @@ namespace ADDON
* class.
*/
//@{
- static void* create(void* kodiBase, const char* label, const char* label2, const char* icon_image, const char* path);
- static void destroy(void* kodiBase, void* handle);
- static char* get_label(void* kodiBase, void* handle);
- static void set_label(void* kodiBase, void* handle, const char* label);
- static char* get_label2(void* kodiBase, void* handle);
- static void set_label2(void* kodiBase, void* handle, const char* label);
- static char* get_art(void* kodiBase, void* handle, const char* type);
- static void set_art(void* kodiBase, void* handle, const char* type, const char* image);
- static char* get_path(void* kodiBase, void* handle);
- static void set_path(void* kodiBase, void* handle, const char* path);
- static char* get_property(void* kodiBase, void* handle, const char* key);
- static void set_property(void* kodiBase, void* handle, const char* key, const char* value);
- static void select(void* kodiBase, void* handle, bool select);
- static bool is_selected(void* kodiBase, void* handle);
+ static KODI_GUI_LISTITEM_HANDLE create(KODI_HANDLE kodiBase,
+ const char* label,
+ const char* label2,
+ const char* path);
+ static void destroy(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ static char* get_label(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ static void set_label(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* label);
+ static char* get_label2(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ static void set_label2(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* label);
+ static char* get_art(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* type);
+ static void set_art(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* type,
+ const char* image);
+ static char* get_path(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
+ static void set_path(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, const char* path);
+ static char* get_property(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* key);
+ static void set_property(KODI_HANDLE kodiBase,
+ KODI_GUI_LISTITEM_HANDLE handle,
+ const char* key,
+ const char* value);
+ static void select(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle, bool select);
+ static bool is_selected(KODI_HANDLE kodiBase, KODI_GUI_LISTITEM_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/Window.cpp b/xbmc/addons/interfaces/gui/Window.cpp
index 2c92de3a65..d4ef5ef68a 100644
--- a/xbmc/addons/interfaces/gui/Window.cpp
+++ b/xbmc/addons/interfaces/gui/Window.cpp
@@ -10,6 +10,7 @@
#include "Application.h"
#include "FileItem.h"
+#include "GUITranslator.h"
#include "General.h"
#include "ServiceBroker.h"
#include "Window.h"
@@ -31,17 +32,12 @@
using namespace ADDON;
using namespace KODI::MESSAGING;
-using namespace kodi; // addon-dev-kit namespace
-using namespace kodi::gui; // addon-dev-kit namespace
-
-extern "C"
-{
namespace ADDON
{
void Interface_GUIWindow::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->window = static_cast<AddonToKodiFuncTable_kodi_gui_window*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_window)));
+ addonInterface->toKodi->kodi_gui->window = new AddonToKodiFuncTable_kodi_gui_window();
/* Window creation functions */
addonInterface->toKodi->kodi_gui->window->create = create;
@@ -73,7 +69,8 @@ void Interface_GUIWindow::Init(AddonGlobalInterface* addonInterface)
/* List item functions */
addonInterface->toKodi->kodi_gui->window->clear_item_list = clear_item_list;
addonInterface->toKodi->kodi_gui->window->add_list_item = add_list_item;
- addonInterface->toKodi->kodi_gui->window->remove_list_item_from_position = remove_list_item_from_position;
+ addonInterface->toKodi->kodi_gui->window->remove_list_item_from_position =
+ remove_list_item_from_position;
addonInterface->toKodi->kodi_gui->window->remove_list_item = remove_list_item;
addonInterface->toKodi->kodi_gui->window->get_list_item = get_list_item;
addonInterface->toKodi->kodi_gui->window->set_current_list_position = set_current_list_position;
@@ -95,7 +92,8 @@ void Interface_GUIWindow::Init(AddonGlobalInterface* addonInterface)
addonInterface->toKodi->kodi_gui->window->get_control_progress = get_control_progress;
addonInterface->toKodi->kodi_gui->window->get_control_radio_button = get_control_radio_button;
addonInterface->toKodi->kodi_gui->window->get_control_render_addon = get_control_render_addon;
- addonInterface->toKodi->kodi_gui->window->get_control_settings_slider = get_control_settings_slider;
+ addonInterface->toKodi->kodi_gui->window->get_control_settings_slider =
+ get_control_settings_slider;
addonInterface->toKodi->kodi_gui->window->get_control_slider = get_control_slider;
addonInterface->toKodi->kodi_gui->window->get_control_spin = get_control_spin;
addonInterface->toKodi->kodi_gui->window->get_control_text_box = get_control_text_box;
@@ -103,28 +101,36 @@ void Interface_GUIWindow::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIWindow::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->window);
+ delete addonInterface->toKodi->kodi_gui->window;
}
/*!
* Window creation functions
*/
//@{
-void* Interface_GUIWindow::create(void* kodiBase, const char* xml_filename,
- const char* default_skin, bool as_dialog, bool is_media)
+KODI_GUI_WINDOW_HANDLE Interface_GUIWindow::create(KODI_HANDLE kodiBase,
+ const char* xml_filename,
+ const char* default_skin,
+ bool as_dialog,
+ bool is_media)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon || !xml_filename || !default_skin)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - invalid handler data (xml_filename='%p', default_skin='%p') on addon '%s'",
- __FUNCTION__, xml_filename, default_skin, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (xml_filename='{}', "
+ "default_skin='{}') on addon '{}'",
+ __func__, static_cast<const void*>(xml_filename),
+ static_cast<const void*>(default_skin), addon ? addon->ID() : "unknown");
return nullptr;
}
if (as_dialog && is_media)
{
- CLog::Log(LOGWARNING, "Interface_GUIWindow::%s: %s/%s - addon tries to create dialog as media window who not allowed, contact Developer '%s' of this addon",
- __FUNCTION__, CAddonInfo::TranslateType(addon->Type()).c_str(), addon->Name().c_str(), addon->Author().c_str());
+ CLog::Log(LOGWARNING,
+ "Interface_GUIWindow::{}: {}/{} - addon tries to create dialog as media window who "
+ "not allowed, contact Developer '{}' of this addon",
+ __func__, CAddonInfo::TranslateType(addon->Type()), addon->Name(), addon->Author());
}
RESOLUTION_INFO res;
@@ -162,8 +168,11 @@ void* Interface_GUIWindow::create(void* kodiBase, const char* xml_filename,
strSkinPath = skinInfo->GetSkinPath(xml_filename, &res);
if (!XFILE::CFile::Exists(strSkinPath))
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s: %s/%s - XML File '%s' for Window is missing, contact Developer '%s' of this addon",
- __FUNCTION__, CAddonInfo::TranslateType(addon->Type()).c_str(), addon->Name().c_str(), strSkinPath.c_str(), addon->Author().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{}: {}/{} - XML File '{}' for Window is missing, contact "
+ "Developer '{}' of this addon",
+ __func__, CAddonInfo::TranslateType(addon->Type()), addon->Name(), strSkinPath,
+ addon->Author());
return nullptr;
}
}
@@ -173,7 +182,7 @@ void* Interface_GUIWindow::create(void* kodiBase, const char* xml_filename,
if (id < 0)
return nullptr;
- CGUIWindow *window;
+ CGUIWindow* window;
if (!as_dialog)
window = new CGUIAddonWindow(id, strSkinPath, addon, is_media);
else
@@ -185,8 +194,9 @@ void* Interface_GUIWindow::create(void* kodiBase, const char* xml_filename,
if (!CServiceBroker::GetGUI()->GetWindowManager().GetWindow(id))
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - Requested window id '%i' does not exist for addon '%s'",
- __FUNCTION__, id, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - Requested window id '{}' does not exist for addon '{}'",
+ __func__, id, addon->ID());
delete window;
return nullptr;
}
@@ -194,25 +204,28 @@ void* Interface_GUIWindow::create(void* kodiBase, const char* xml_filename,
return window;
}
-void Interface_GUIWindow::destroy(void* kodiBase, void* handle)
+void Interface_GUIWindow::destroy(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon ? addon->ID() : "unknown");
return;
}
Interface_GUIGeneral::lock();
- CGUIWindow *pWindow = CServiceBroker::GetGUI()->GetWindowManager().GetWindow(pAddonWindow->GetID());
+ CGUIWindow* pWindow =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow(pAddonWindow->GetID());
if (pWindow)
{
// first change to an existing window
- if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == pAddonWindow->GetID() && !g_application.m_bStop)
+ if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == pAddonWindow->GetID() &&
+ !g_application.m_bStop)
{
- if(CServiceBroker::GetGUI()->GetWindowManager().GetWindow(pAddonWindow->m_oldWindowId))
+ if (CServiceBroker::GetGUI()->GetWindowManager().GetWindow(pAddonWindow->m_oldWindowId))
CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(pAddonWindow->m_oldWindowId);
else // old window does not exist anymore, switch to home
CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_HOME);
@@ -228,20 +241,25 @@ void Interface_GUIWindow::destroy(void* kodiBase, void* handle)
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::set_callbacks(void* kodiBase, void* handle, void* clienthandle,
- bool (*CBOnInit)(void*),
- bool (*CBOnFocus)(void*, int),
- bool (*CBOnClick)(void*, int),
- bool (*CBOnAction)(void*, int, uint32_t, wchar_t),
- void (*CBGetContextButtons)(void* , int, gui_context_menu_pair*, unsigned int*),
- bool (*CBOnContextButton)(void*, int, unsigned int))
+void Interface_GUIWindow::set_callbacks(
+ KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_CLIENT_HANDLE clienthandle,
+ bool (*CBOnInit)(KODI_GUI_CLIENT_HANDLE),
+ bool (*CBOnFocus)(KODI_GUI_CLIENT_HANDLE, int),
+ bool (*CBOnClick)(KODI_GUI_CLIENT_HANDLE, int),
+ bool (*CBOnAction)(KODI_GUI_CLIENT_HANDLE, ADDON_ACTION),
+ void (*CBGetContextButtons)(KODI_GUI_CLIENT_HANDLE, int, gui_context_menu_pair*, unsigned int*),
+ bool (*CBOnContextButton)(KODI_GUI_CLIENT_HANDLE, int, unsigned int))
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !clienthandle)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - invalid handler data (handle='%p', clienthandle='%p') on addon '%s'",
- __FUNCTION__, handle, clienthandle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (handle='{}', clienthandle='{}') "
+ "on addon '{}'",
+ __func__, handle, clienthandle, addon ? addon->ID() : "unknown");
return;
}
@@ -256,14 +274,15 @@ void Interface_GUIWindow::set_callbacks(void* kodiBase, void* handle, void* clie
Interface_GUIGeneral::unlock();
}
-bool Interface_GUIWindow::show(void* kodiBase, void* handle)
+bool Interface_GUIWindow::show(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon ? addon->ID() : "unknown");
return false;
}
@@ -281,14 +300,15 @@ bool Interface_GUIWindow::show(void* kodiBase, void* handle)
return true;
}
-bool Interface_GUIWindow::close(void* kodiBase, void* handle)
+bool Interface_GUIWindow::close(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon ? addon->ID() : "unknown");
return false;
}
@@ -308,14 +328,15 @@ bool Interface_GUIWindow::close(void* kodiBase, void* handle)
return true;
}
-bool Interface_GUIWindow::do_modal(void* kodiBase, void* handle)
+bool Interface_GUIWindow::do_modal(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon ? addon->ID() : "unknown");
return false;
}
@@ -341,23 +362,25 @@ bool Interface_GUIWindow::do_modal(void* kodiBase, void* handle)
* Window control functions
*/
//@{
-bool Interface_GUIWindow::set_focus_id(void* kodiBase, void* handle, int control_id)
+bool Interface_GUIWindow::set_focus_id(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return false;
}
if (!pAddonWindow->GetControl(control_id))
{
- CLog::Log(LOGERROR, "Interface_GUIWindow - %s: %s - Control does not exist in window",
- __FUNCTION__, addon->Name().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIWindow - {}: {} - Control does not exist in window", __func__,
+ addon->Name());
return false;
}
@@ -369,16 +392,16 @@ bool Interface_GUIWindow::set_focus_id(void* kodiBase, void* handle, int control
return true;
}
-int Interface_GUIWindow::get_focus_id(void* kodiBase, void* handle)
+int Interface_GUIWindow::get_focus_id(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return -1;
}
@@ -387,22 +410,26 @@ int Interface_GUIWindow::get_focus_id(void* kodiBase, void* handle)
Interface_GUIGeneral::unlock();
if (control_id == -1)
- CLog::Log(LOGERROR, "Interface_GUIWindow - %s: %s - No control in this window has focus",
- __FUNCTION__, addon->Name().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIWindow - {}: {} - No control in this window has focus",
+ __func__, addon->Name());
return control_id;
}
-void Interface_GUIWindow::set_control_label(void* kodiBase, void* handle, int control_id, const char *label)
+void Interface_GUIWindow::set_control_label(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !label)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -413,15 +440,19 @@ void Interface_GUIWindow::set_control_label(void* kodiBase, void* handle, int co
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::set_control_visible(void* kodiBase, void* handle, int control_id, bool visible)
+void Interface_GUIWindow::set_control_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -431,20 +462,25 @@ void Interface_GUIWindow::set_control_visible(void* kodiBase, void* handle, int
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::set_control_selected(void* kodiBase, void* handle, int control_id, bool selected)
+void Interface_GUIWindow::set_control_selected(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ bool selected)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
Interface_GUIGeneral::lock();
- CGUIMessage msg(selected ? GUI_MSG_SET_SELECTED : GUI_MSG_SET_DESELECTED, pAddonWindow->m_windowId, control_id);
+ CGUIMessage msg(selected ? GUI_MSG_SET_SELECTED : GUI_MSG_SET_DESELECTED,
+ pAddonWindow->m_windowId, control_id);
pAddonWindow->OnMessage(msg);
Interface_GUIGeneral::unlock();
}
@@ -454,16 +490,20 @@ void Interface_GUIWindow::set_control_selected(void* kodiBase, void* handle, int
* Window property functions
*/
//@{
-void Interface_GUIWindow::set_property(void* kodiBase, void* handle, const char *key, const char *value)
+void Interface_GUIWindow::set_property(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ const char* value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key || !value)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p', value='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, value, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}', value='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ static_cast<const void*>(value), addon ? addon->ID() : "unknown");
return;
}
@@ -475,16 +515,20 @@ void Interface_GUIWindow::set_property(void* kodiBase, void* handle, const char
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::set_property_int(void* kodiBase, void* handle, const char *key, int value)
+void Interface_GUIWindow::set_property_int(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ int value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -496,16 +540,20 @@ void Interface_GUIWindow::set_property_int(void* kodiBase, void* handle, const c
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::set_property_bool(void* kodiBase, void* handle, const char *key, bool value)
+void Interface_GUIWindow::set_property_bool(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ bool value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -517,16 +565,20 @@ void Interface_GUIWindow::set_property_bool(void* kodiBase, void* handle, const
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::set_property_double(void* kodiBase, void* handle, const char *key, double value)
+void Interface_GUIWindow::set_property_double(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ double value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -538,16 +590,19 @@ void Interface_GUIWindow::set_property_double(void* kodiBase, void* handle, cons
Interface_GUIGeneral::unlock();
}
-char* Interface_GUIWindow::get_property(void* kodiBase, void* handle, const char *key)
+char* Interface_GUIWindow::get_property(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return nullptr;
}
@@ -561,16 +616,19 @@ char* Interface_GUIWindow::get_property(void* kodiBase, void* handle, const char
return strdup(value.c_str());
}
-int Interface_GUIWindow::get_property_int(void* kodiBase, void* handle, const char *key)
+int Interface_GUIWindow::get_property_int(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return -1;
}
@@ -584,16 +642,19 @@ int Interface_GUIWindow::get_property_int(void* kodiBase, void* handle, const ch
return value;
}
-bool Interface_GUIWindow::get_property_bool(void* kodiBase, void* handle, const char *key)
+bool Interface_GUIWindow::get_property_bool(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return false;
}
@@ -607,16 +668,19 @@ bool Interface_GUIWindow::get_property_bool(void* kodiBase, void* handle, const
return value;
}
-double Interface_GUIWindow::get_property_double(void* kodiBase, void* handle, const char *key)
+double Interface_GUIWindow::get_property_double(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return 0.0;
}
@@ -630,16 +694,16 @@ double Interface_GUIWindow::get_property_double(void* kodiBase, void* handle, co
return value;
}
-void Interface_GUIWindow::clear_properties(void* kodiBase, void* handle)
+void Interface_GUIWindow::clear_properties(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -648,16 +712,19 @@ void Interface_GUIWindow::clear_properties(void* kodiBase, void* handle)
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::clear_property(void* kodiBase, void* handle, const char *key)
+void Interface_GUIWindow::clear_property(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -674,16 +741,16 @@ void Interface_GUIWindow::clear_property(void* kodiBase, void* handle, const cha
* List item functions
*/
//@{
-void Interface_GUIWindow::clear_item_list(void* kodiBase, void* handle)
+void Interface_GUIWindow::clear_item_list(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -692,24 +759,27 @@ void Interface_GUIWindow::clear_item_list(void* kodiBase, void* handle)
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::add_list_item(void* kodiBase, void* handle, void* item, int list_position)
+void Interface_GUIWindow::add_list_item(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_LISTITEM_HANDLE item,
+ int list_position)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !item)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "item='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, item, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "item='{}') on addon '{}'",
+ __func__, kodiBase, handle, item, addon ? addon->ID() : "unknown");
return;
}
CFileItemPtr* pItem(static_cast<CFileItemPtr*>(item));
if (pItem->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIWindow::{} - empty list item called on addon '{}'", __func__,
+ addon->ID());
return;
}
@@ -718,16 +788,18 @@ void Interface_GUIWindow::add_list_item(void* kodiBase, void* handle, void* item
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::remove_list_item_from_position(void* kodiBase, void* handle, int list_position)
+void Interface_GUIWindow::remove_list_item_from_position(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -736,24 +808,26 @@ void Interface_GUIWindow::remove_list_item_from_position(void* kodiBase, void* h
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::remove_list_item(void* kodiBase, void* handle, void* item)
+void Interface_GUIWindow::remove_list_item(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_LISTITEM_HANDLE item)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !item)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "item='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, item, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "item='{}') on addon '{}'",
+ __func__, kodiBase, handle, item, addon ? addon->ID() : "unknown");
return;
}
CFileItemPtr* pItem(static_cast<CFileItemPtr*>(item));
if (pItem->get() == nullptr)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - empty list item called on addon '%s'",
- __FUNCTION__, addon->ID().c_str());
+ CLog::Log(LOGERROR, "Interface_GUIWindow::{} - empty list item called on addon '{}'", __func__,
+ addon->ID());
return;
}
@@ -762,14 +836,18 @@ void Interface_GUIWindow::remove_list_item(void* kodiBase, void* handle, void* i
Interface_GUIGeneral::unlock();
}
-void* Interface_GUIWindow::get_list_item(void* kodiBase, void* handle, int list_position)
+KODI_GUI_LISTITEM_HANDLE Interface_GUIWindow::get_list_item(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
@@ -777,7 +855,8 @@ void* Interface_GUIWindow::get_list_item(void* kodiBase, void* handle, int list_
CFileItemPtr* pItem(pAddonWindow->GetListItem(list_position));
if (pItem == nullptr || pItem->get() == nullptr)
{
- CLog::Log(LOGERROR, "ADDON::Interface_GUIWindow - %s: %s - Index out of range", __FUNCTION__, addon->Name().c_str());
+ CLog::Log(LOGERROR, "ADDON::Interface_GUIWindow - {}: {} - Index out of range", __func__,
+ addon->Name());
if (pItem)
{
@@ -790,16 +869,18 @@ void* Interface_GUIWindow::get_list_item(void* kodiBase, void* handle, int list_
return pItem;
}
-void Interface_GUIWindow::set_current_list_position(void* kodiBase, void* handle, int list_position)
+void Interface_GUIWindow::set_current_list_position(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -808,16 +889,17 @@ void Interface_GUIWindow::set_current_list_position(void* kodiBase, void* handle
Interface_GUIGeneral::unlock();
}
-int Interface_GUIWindow::get_current_list_position(void* kodiBase, void* handle)
+int Interface_GUIWindow::get_current_list_position(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return -1;
}
@@ -828,16 +910,16 @@ int Interface_GUIWindow::get_current_list_position(void* kodiBase, void* handle)
return listPos;
}
-int Interface_GUIWindow::get_list_size(void* kodiBase, void* handle)
+int Interface_GUIWindow::get_list_size(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return -1;
}
@@ -848,16 +930,20 @@ int Interface_GUIWindow::get_list_size(void* kodiBase, void* handle)
return listSize;
}
-void Interface_GUIWindow::set_container_property(void* kodiBase, void* handle, const char* key, const char* value)
+void Interface_GUIWindow::set_container_property(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ const char* value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !key || !value)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "key='%p', value='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, key, value, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "key='{}', value='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(key),
+ static_cast<const void*>(value), addon ? addon->ID() : "unknown");
return;
}
@@ -866,16 +952,19 @@ void Interface_GUIWindow::set_container_property(void* kodiBase, void* handle, c
Interface_GUIGeneral::unlock();
}
-void Interface_GUIWindow::set_container_content(void* kodiBase, void* handle, const char* value)
+void Interface_GUIWindow::set_container_content(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow || !value)
{
CLog::Log(LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "value='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, value, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "value='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(value),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -884,16 +973,17 @@ void Interface_GUIWindow::set_container_content(void* kodiBase, void* handle, co
Interface_GUIGeneral::unlock();
}
-int Interface_GUIWindow::get_current_container_id(void* kodiBase, void* handle)
+int Interface_GUIWindow::get_current_container_id(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return -1;
}
@@ -909,16 +999,16 @@ int Interface_GUIWindow::get_current_container_id(void* kodiBase, void* handle)
* Various functions
*/
//@{
-void Interface_GUIWindow::mark_dirty_region(void* kodiBase, void* handle)
+void Interface_GUIWindow::mark_dirty_region(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -932,81 +1022,118 @@ void Interface_GUIWindow::mark_dirty_region(void* kodiBase, void* handle)
* GUI control access functions
*/
//@{
-void* Interface_GUIWindow::get_control_button(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_button(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_BUTTON, "button");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_BUTTON,
+ "button");
}
-void* Interface_GUIWindow::get_control_edit(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_edit(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_EDIT, "edit");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_EDIT, "edit");
}
-void* Interface_GUIWindow::get_control_fade_label(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_fade_label(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_FADELABEL, "fade label");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_FADELABEL,
+ "fade label");
}
-void* Interface_GUIWindow::get_control_image(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_image(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_IMAGE, "image");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_IMAGE, "image");
}
-void* Interface_GUIWindow::get_control_label(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_label(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_LABEL, "label");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_LABEL, "label");
}
-void* Interface_GUIWindow::get_control_progress(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_progress(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_PROGRESS, "progress");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_PROGRESS,
+ "progress");
}
-void* Interface_GUIWindow::get_control_radio_button(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_radio_button(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_RADIO, "radio button");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_RADIO,
+ "radio button");
}
-void* Interface_GUIWindow::get_control_render_addon(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_render_addon(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- CGUIControl* pGUIControl = static_cast<CGUIControl*>(GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_RENDERADDON, "renderaddon"));
+ CGUIControl* pGUIControl = static_cast<CGUIControl*>(GetControl(
+ kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_RENDERADDON, "renderaddon"));
if (!pGUIControl)
return nullptr;
- CGUIAddonRenderingControl *pRenderControl = new CGUIAddonRenderingControl(dynamic_cast<CGUIRenderingControl*>(pGUIControl));
+ CGUIAddonRenderingControl* pRenderControl =
+ new CGUIAddonRenderingControl(dynamic_cast<CGUIRenderingControl*>(pGUIControl));
return pRenderControl;
}
-void* Interface_GUIWindow::get_control_settings_slider(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_settings_slider(
+ KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_SETTINGS_SLIDER, "settings slider");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_SETTINGS_SLIDER,
+ "settings slider");
}
-void* Interface_GUIWindow::get_control_slider(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_slider(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_SLIDER, "slider");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_SLIDER,
+ "slider");
}
-void* Interface_GUIWindow::get_control_spin(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_spin(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_SPINEX, "spin");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_SPINEX, "spin");
}
-void* Interface_GUIWindow::get_control_text_box(void* kodiBase, void* handle, int control_id)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::get_control_text_box(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id)
{
- return GetControl(kodiBase, handle, control_id, __FUNCTION__, CGUIControl::GUICONTROL_TEXTBOX, "textbox");
+ return GetControl(kodiBase, handle, control_id, __func__, CGUIControl::GUICONTROL_TEXTBOX,
+ "textbox");
}
//@}
-void* Interface_GUIWindow::GetControl(void* kodiBase, void* handle, int control_id, const char* function, CGUIControl::GUICONTROLTYPES type, const std::string& typeName)
+KODI_GUI_CONTROL_HANDLE Interface_GUIWindow::GetControl(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ const char* function,
+ CGUIControl::GUICONTROLTYPES type,
+ const std::string& typeName)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonWindow* pAddonWindow = static_cast<CGUIAddonWindow*>(handle);
if (!addon || !pAddonWindow)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIWindow::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- function, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - invalid handler data (kodiBase='{}', handle='{}') on "
+ "addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
@@ -1021,14 +1148,17 @@ int Interface_GUIWindow::GetNextAvailableWindowId()
if (CServiceBroker::GetGUI()->GetWindowManager().GetWindow(WINDOW_ADDON_END))
{
Interface_GUIGeneral::unlock();
- CLog::Log(LOGERROR, "Interface_GUIWindow::%s - Maximum number of windows for binary addons reached", __FUNCTION__);
+ CLog::Log(LOGERROR,
+ "Interface_GUIWindow::{} - Maximum number of windows for binary addons reached",
+ __func__);
return -1;
}
// window id's WINDOW_ADDON_START - WINDOW_ADDON_END are reserved for addons
// get first window id that is not in use
int id = WINDOW_ADDON_START;
- while (id < WINDOW_ADDON_END && CServiceBroker::GetGUI()->GetWindowManager().GetWindow(id) != nullptr)
+ while (id < WINDOW_ADDON_END &&
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow(id) != nullptr)
id++;
Interface_GUIGeneral::unlock();
@@ -1036,40 +1166,54 @@ int Interface_GUIWindow::GetNextAvailableWindowId()
}
CGUIAddonWindow::CGUIAddonWindow(int id, const std::string& strXML, CAddonDll* addon, bool isMedia)
- : CGUIMediaWindow(id, strXML.c_str()),
- m_clientHandle{nullptr},
- CBOnInit{nullptr},
- CBOnFocus{nullptr},
- CBOnClick{nullptr},
- CBOnAction{nullptr},
- CBGetContextButtons{nullptr},
- CBOnContextButton{nullptr},
- m_windowId(id),
- m_oldWindowId(0),
- m_actionEvent(true),
- m_addon(addon),
- m_isMedia(isMedia)
+ : CGUIMediaWindow(id, strXML.c_str()),
+ m_clientHandle{nullptr},
+ CBOnInit{nullptr},
+ CBOnFocus{nullptr},
+ CBOnClick{nullptr},
+ CBOnAction{nullptr},
+ CBGetContextButtons{nullptr},
+ CBOnContextButton{nullptr},
+ m_windowId(id),
+ m_oldWindowId(0),
+ m_actionEvent(true),
+ m_addon(addon),
+ m_isMedia(isMedia)
{
m_loadType = LOAD_ON_GUI_INIT;
}
-CGUIControl* CGUIAddonWindow::GetAddonControl(int controlId, CGUIControl::GUICONTROLTYPES type, const std::string& typeName)
+CGUIControl* CGUIAddonWindow::GetAddonControl(int controlId,
+ CGUIControl::GUICONTROLTYPES type,
+ const std::string& typeName)
{
+ // Load window resources, if not already done, to have related xml content
+ // present and to let control find it
+ if (!m_windowLoaded)
+ {
+ if (!Initialize())
+ {
+ CLog::Log(LOGERROR,
+ "CGUIAddonGUI_Window::{}: {} - Window initialize failed by control id '{}' request "
+ "for '{}'",
+ __func__, m_addon->Name(), controlId, typeName);
+ return nullptr;
+ }
+ }
+
CGUIControl* pGUIControl = GetControl(controlId);
if (!pGUIControl)
{
- CLog::Log(LOGERROR, "CGUIAddonGUI_Window::%s: %s - Requested GUI control Id '%i' for '%s' not present!",
- __FUNCTION__,
- m_addon->Name().c_str(),
- controlId, typeName.c_str());
+ CLog::Log(LOGERROR,
+ "CGUIAddonGUI_Window::{}: {} - Requested GUI control Id '{}' for '{}' not present!",
+ __func__, m_addon->Name(), controlId, typeName);
return nullptr;
}
else if (pGUIControl->GetControlType() != type)
{
- CLog::Log(LOGERROR, "CGUIAddonGUI_Window::%s: %s - Requested GUI control Id '%i' not the type '%s'!",
- __FUNCTION__,
- m_addon->Name().c_str(),
- controlId, typeName.c_str());
+ CLog::Log(LOGERROR,
+ "CGUIAddonGUI_Window::{}: {} - Requested GUI control Id '{}' not the type '{}'!",
+ __func__, m_addon->Name(), controlId, typeName);
return nullptr;
}
@@ -1079,7 +1223,8 @@ CGUIControl* CGUIAddonWindow::GetAddonControl(int controlId, CGUIControl::GUICON
bool CGUIAddonWindow::OnAction(const CAction& action)
{
// Let addon decide whether it wants to handle action first
- if (CBOnAction && CBOnAction(m_clientHandle, action.GetID(), action.GetButtonCode(), action.GetUnicode()))
+ if (CBOnAction &&
+ CBOnAction(m_clientHandle, CAddonGUITranslator::TranslateActionIdToAddon(action.GetID())))
return true;
return CGUIWindow::OnAction(action);
@@ -1123,7 +1268,8 @@ bool CGUIAddonWindow::OnMessage(CGUIMessage& message)
case GUI_MSG_NOTIFY_ALL:
{
// most messages from GUI_MSG_NOTIFY_ALL break container content, whitelist working ones.
- if (message.GetParam1() == GUI_MSG_PAGE_CHANGE || message.GetParam1() == GUI_MSG_WINDOW_RESIZE)
+ if (message.GetParam1() == GUI_MSG_PAGE_CHANGE ||
+ message.GetParam1() == GUI_MSG_WINDOW_RESIZE)
return CGUIMediaWindow::OnMessage(message);
return true;
}
@@ -1141,19 +1287,20 @@ bool CGUIAddonWindow::OnMessage(CGUIMessage& message)
{
if ((controlClicked->IsContainer() && (message.GetParam1() == ACTION_SELECT_ITEM ||
message.GetParam1() == ACTION_MOUSE_LEFT_CLICK)) ||
- !controlClicked->IsContainer())
+ !controlClicked->IsContainer())
{
if (CBOnClick)
return CBOnClick(m_clientHandle, iControl);
}
- else if (controlClicked->IsContainer() && (message.GetParam1() == ACTION_MOUSE_RIGHT_CLICK ||
- message.GetParam1() == ACTION_CONTEXT_MENU))
+ else if (controlClicked->IsContainer() &&
+ (message.GetParam1() == ACTION_MOUSE_RIGHT_CLICK ||
+ message.GetParam1() == ACTION_CONTEXT_MENU))
{
if (CBOnAction)
{
// Check addon want to handle right click for a context menu, if
// not used from addon becomes "GetContextButtons(...)" called.
- if (CBOnAction(m_clientHandle, ACTION_CONTEXT_MENU, 0, 0))
+ if (CBOnAction(m_clientHandle, ADDON_ACTION_CONTEXT_MENU))
return true;
}
}
@@ -1192,7 +1339,7 @@ void CGUIAddonWindow::AddItem(CFileItemPtr* fileItem, int itemPosition)
{
m_vecItems->Add(*fileItem);
}
- else if (itemPosition < -1 && !(itemPosition-1 < m_vecItems->Size()))
+ else if (itemPosition < -1 && !(itemPosition - 1 < m_vecItems->Size()))
{
m_vecItems->AddFront(*fileItem, 0);
}
@@ -1300,8 +1447,7 @@ void CGUIAddonWindow::SetupShares()
CGUIAddonWindowDialog::CGUIAddonWindowDialog(int id, const std::string& strXML, CAddonDll* addon)
- : CGUIAddonWindow(id, strXML, addon, false),
- m_bRunning(false)
+ : CGUIAddonWindow(id, strXML, addon, false), m_bRunning(false)
{
}
@@ -1310,11 +1456,13 @@ void CGUIAddonWindowDialog::Show(bool show /* = true */, bool modal /* = true*/)
if (modal)
{
unsigned int count = CServiceBroker::GetWinSystem()->GetGfxContext().exit();
- CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ADDON_DIALOG, 0, show ? 1 : 0, static_cast<void*>(this));
+ CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ADDON_DIALOG, 0, show ? 1 : 0,
+ static_cast<void*>(this));
CServiceBroker::GetWinSystem()->GetGfxContext().restore(count);
}
else
- CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ADDON_DIALOG, 0, show ? 1 : 0, static_cast<void*>(this));
+ CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ADDON_DIALOG, 0, show ? 1 : 0,
+ static_cast<void*>(this));
}
void CGUIAddonWindowDialog::Show_Internal(bool show /* = true */)
@@ -1349,4 +1497,3 @@ void CGUIAddonWindowDialog::Show_Internal(bool show /* = true */)
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/Window.h b/xbmc/addons/interfaces/gui/Window.h
index de174eee87..dc337f5156 100644
--- a/xbmc/addons/interfaces/gui/Window.h
+++ b/xbmc/addons/interfaces/gui/Window.h
@@ -8,17 +8,18 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/window.h"
#include "threads/Event.h"
#include "windows/GUIMediaWindow.h"
extern "C"
{
-struct AddonGlobalInterface;
-struct gui_context_menu_pair;
+ struct AddonGlobalInterface;
+ struct gui_context_menu_pair;
-namespace ADDON
-{
+ namespace ADDON
+ {
class CAddonDll;
/*!
@@ -46,86 +47,167 @@ namespace ADDON
*/
//@{
/* Window creation functions */
- static void* create(void* kodiBase, const char* xml_filename, const char* default_skin, bool as_dialog, bool is_media);
- static void destroy(void* kodiBase, void* handle);
- static void set_callbacks(void* kodiBase,
- void* handle,
- void* clienthandle,
- bool (*CBInit)(void*),
- bool (*CBFocus)(void*, int),
- bool (*CBClick)(void*, int),
- bool (*CBOnAction)(void*, int, uint32_t, wchar_t),
- void (*CBGetContextButtons)(void* , int, gui_context_menu_pair*, unsigned int*),
- bool (*CBOnContextButton)(void*, int, unsigned int));
- static bool show(void* kodiBase, void* handle);
- static bool close(void* kodiBase, void* handle);
- static bool do_modal(void* kodiBase, void* handle);
+ static KODI_GUI_WINDOW_HANDLE create(KODI_HANDLE kodiBase,
+ const char* xml_filename,
+ const char* default_skin,
+ bool as_dialog,
+ bool is_media);
+ static void destroy(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static 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, ADDON_ACTION),
+ void (*CBGetContextButtons)(KODI_GUI_CLIENT_HANDLE,
+ int,
+ gui_context_menu_pair*,
+ unsigned int*),
+ bool (*CBOnContextButton)(KODI_GUI_CLIENT_HANDLE, int, unsigned int));
+ static bool show(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static bool close(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static bool do_modal(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
/* Window control functions */
- static bool set_focus_id(void* kodiBase, void* handle, int control_id);
- static int get_focus_id(void* kodiBase, void* handle);
- static void set_control_label(void* kodiBase, void* handle, int control_id, const char* label);
- static void set_control_visible(void* kodiBase, void* handle, int control_id, bool visible);
- static void set_control_selected(void* kodiBase, void* handle, int control_id, bool selected);
+ static bool set_focus_id(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, int control_id);
+ static int get_focus_id(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static void set_control_label(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ const char* label);
+ static void set_control_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ bool visible);
+ static void set_control_selected(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ bool selected);
/* Window property functions */
- static void set_property(void* kodiBase, void* handle, const char* key, const char* value);
- static void set_property_int(void* kodiBase, void* handle, const char* key, int value);
- static void set_property_bool(void* kodiBase, void* handle, const char* key, bool value);
- static void set_property_double(void* kodiBase, void* handle, const char* key, double value);
- static char* get_property(void* kodiBase, void* handle, const char* key);
- static int get_property_int(void* kodiBase, void* handle, const char* key);
- static bool get_property_bool(void* kodiBase, void* handle, const char* key);
- static double get_property_double(void* kodiBase, void* handle, const char* key);
- static void clear_properties(void* kodiBase, void* handle);
- static void clear_property(void* kodiBase, void* handle, const char* key);
+ static void set_property(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ const char* value);
+ static void set_property_int(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ int value);
+ static void set_property_bool(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ bool value);
+ static void set_property_double(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ double value);
+ static char* get_property(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle, const char* key);
+ static int get_property_int(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key);
+ static bool get_property_bool(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key);
+ static double get_property_double(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key);
+ static void clear_properties(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static void clear_property(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key);
/* List item functions */
- static void clear_item_list(void* kodiBase, void* handle);
- static void add_list_item(void* kodiBase, void* handle, void* item, int list_position);
- static void remove_list_item_from_position(void* kodiBase, void* handle, int list_position);
- static void remove_list_item(void* kodiBase, void* handle, void* item);
- static void* get_list_item(void* kodiBase, void* handle, int list_position);
- static void set_current_list_position(void* kodiBase, void* handle, int list_position);
- static int get_current_list_position(void* kodiBase, void* handle);
- static int get_list_size(void* kodiBase, void* handle);
- static void set_container_property(void* kodiBase, void* handle, const char* key, const char* value);
- static void set_container_content(void* kodiBase, void* handle, const char* value);
- static int get_current_container_id(void* kodiBase, void* handle);
+ static void clear_item_list(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static void add_list_item(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_LISTITEM_HANDLE item,
+ int list_position);
+ static void remove_list_item_from_position(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position);
+ static void remove_list_item(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ KODI_GUI_LISTITEM_HANDLE item);
+ static KODI_GUI_LISTITEM_HANDLE get_list_item(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position);
+ static void set_current_list_position(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int list_position);
+ static int get_current_list_position(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static int get_list_size(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
+ static void set_container_property(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* key,
+ const char* value);
+ static void set_container_content(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ const char* value);
+ static int get_current_container_id(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
/* Various functions */
- static void mark_dirty_region(void* kodiBase, void* handle);
+ static void mark_dirty_region(KODI_HANDLE kodiBase, KODI_GUI_WINDOW_HANDLE handle);
/* GUI control access functions */
- static void* get_control_button(void* kodiBase, void* handle, int control_id);
- static void* get_control_edit(void* kodiBase, void* handle, int control_id);
- static void* get_control_fade_label(void* kodiBase, void* handle, int control_id);
- static void* get_control_image(void* kodiBase, void* handle, int control_id);
- static void* get_control_label(void* kodiBase, void* handle, int control_id);
- static void* get_control_radio_button(void* kodiBase, void* handle, int control_id);
- static void* get_control_progress(void* kodiBase, void* handle, int control_id);
- static void* get_control_render_addon(void* kodiBase, void* handle, int control_id);
- static void* get_control_settings_slider(void* kodiBase, void* handle, int control_id);
- static void* get_control_slider(void* kodiBase, void* handle, int control_id);
- static void* get_control_spin(void* kodiBase, void* handle, int control_id);
- static void* get_control_text_box(void* kodiBase, void* handle, int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_button(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_edit(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_fade_label(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_image(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_label(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_radio_button(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_progress(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_render_addon(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_settings_slider(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_slider(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_spin(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
+ static KODI_GUI_CONTROL_HANDLE get_control_text_box(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id);
//@}
private:
- static void* GetControl(void* kodiBase, void* handle, int control_id, const char* function, CGUIControl::GUICONTROLTYPES type, const std::string& typeName);
+ static KODI_GUI_CONTROL_HANDLE GetControl(KODI_HANDLE kodiBase,
+ KODI_GUI_WINDOW_HANDLE handle,
+ int control_id,
+ const char* function,
+ CGUIControl::GUICONTROLTYPES type,
+ const std::string& typeName);
static int GetNextAvailableWindowId();
};
class CGUIAddonWindow : public CGUIMediaWindow
{
- friend struct Interface_GUIWindow;
+ friend struct Interface_GUIWindow;
public:
CGUIAddonWindow(int id, const std::string& strXML, ADDON::CAddonDll* addon, bool isMedia);
~CGUIAddonWindow() override = default;
bool OnMessage(CGUIMessage& message) override;
- bool OnAction(const CAction &action) override;
+ bool OnAction(const CAction& action) override;
void AllocResources(bool forceLoad = false) override;
void Render() override;
bool IsMediaWindow() const override { return m_isMedia; }
@@ -143,21 +225,26 @@ namespace ADDON
void SetContainerProperty(const std::string& key, const std::string& value);
void SetContainerContent(const std::string& value);
int GetCurrentContainerControlId();
- CGUIControl* GetAddonControl(int controlId, CGUIControl::GUICONTROLTYPES type, const std::string& typeName);
+ CGUIControl* GetAddonControl(int controlId,
+ CGUIControl::GUICONTROLTYPES type,
+ const std::string& typeName);
protected:
- void GetContextButtons(int itemNumber, CContextButtons &buttons) override;
+ void GetContextButtons(int itemNumber, CContextButtons& buttons) override;
bool OnContextButton(int itemNumber, CONTEXT_BUTTON button) override;
void SetupShares() override;
/* kodi to addon callback function addresses */
- void* m_clientHandle;
- bool (*CBOnInit)(void* cbhdl);
- bool (*CBOnFocus)(void* cbhdl, int controlId);
- bool (*CBOnClick)(void* cbhdl, int controlId);
- bool (*CBOnAction)(void* cbhdl, int actionId, uint32_t buttoncode, wchar_t unicode);
- void (*CBGetContextButtons)(void* cbhdl, int itemNumber, gui_context_menu_pair* buttons, unsigned int* size);
- bool (*CBOnContextButton)(void* cbhdl, int itemNumber, unsigned int button);
+ KODI_GUI_CLIENT_HANDLE m_clientHandle;
+ bool (*CBOnInit)(KODI_GUI_CLIENT_HANDLE cbhdl);
+ bool (*CBOnFocus)(KODI_GUI_CLIENT_HANDLE cbhdl, int controlId);
+ bool (*CBOnClick)(KODI_GUI_CLIENT_HANDLE cbhdl, int controlId);
+ bool (*CBOnAction)(KODI_GUI_CLIENT_HANDLE cbhdl, ADDON_ACTION actionId);
+ void (*CBGetContextButtons)(KODI_GUI_CLIENT_HANDLE cbhdl,
+ int itemNumber,
+ gui_context_menu_pair* buttons,
+ unsigned int* size);
+ bool (*CBOnContextButton)(KODI_GUI_CLIENT_HANDLE cbhdl, int itemNumber, unsigned int button);
const int m_windowId;
int m_oldWindowId;
@@ -178,7 +265,7 @@ namespace ADDON
bool IsDialogRunning() const override { return m_bRunning; }
bool IsDialog() const override { return true; };
- bool IsModalDialog() const override { return true; };
+ bool IsModalDialog() const override { return true; };
void Show(bool show = true, bool modal = true);
void Show_Internal(bool show = true);
@@ -187,5 +274,5 @@ namespace ADDON
bool m_bRunning;
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Button.cpp b/xbmc/addons/interfaces/gui/controls/Button.cpp
index 95939ae7e5..24a99946b0 100644
--- a/xbmc/addons/interfaces/gui/controls/Button.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Button.cpp
@@ -14,14 +14,13 @@
#include "utils/StringUtils.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlButton::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_button = static_cast<AddonToKodiFuncTable_kodi_gui_control_button*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_button)));
+ addonInterface->toKodi->kodi_gui->control_button =
+ new AddonToKodiFuncTable_kodi_gui_control_button();
addonInterface->toKodi->kodi_gui->control_button->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_button->set_enabled = set_enabled;
@@ -35,99 +34,109 @@ void Interface_GUIControlButton::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlButton::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_button);
+ delete addonInterface->toKodi->kodi_gui->control_button;
}
-void Interface_GUIControlButton::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlButton::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIButtonControl* control = static_cast<CGUIButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlButton::%s - invalid handler data (kodiBase='%p', handle='%p') "
- "on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlButton::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlButton::set_enabled(void* kodiBase, void* handle, bool enabled)
+void Interface_GUIControlButton::set_enabled(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool enabled)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIButtonControl* control = static_cast<CGUIButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlButton::%s - invalid handler data (kodiBase='%p', handle='%p') "
- "on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlButton::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetEnabled(enabled);
}
-void Interface_GUIControlButton::set_label(void* kodiBase, void* handle, const char* label)
+void Interface_GUIControlButton::set_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIButtonControl* control = static_cast<CGUIButtonControl*>(handle);
if (!addon || !control || !label)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlButton::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlButton::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
control->SetLabel(label);
}
-char* Interface_GUIControlButton::get_label(void* kodiBase, void* handle)
+char* Interface_GUIControlButton::get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIButtonControl* control = static_cast<CGUIButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlButton::%s - invalid handler data (kodiBase='%p', handle='%p') "
- "on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlButton::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
return strdup(control->GetLabel().c_str());
}
-void Interface_GUIControlButton::set_label2(void* kodiBase, void* handle, const char* label)
+void Interface_GUIControlButton::set_label2(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIButtonControl* control = static_cast<CGUIButtonControl*>(handle);
if (!addon || !control || !label)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlButton::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlButton::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
control->SetLabel2(label);
}
-char* Interface_GUIControlButton::get_label2(void* kodiBase, void* handle)
+char* Interface_GUIControlButton::get_label2(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIButtonControl* control = static_cast<CGUIButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlButton::%s - invalid handler data (kodiBase='%p', handle='%p') "
- "on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlButton::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
@@ -135,4 +144,3 @@ char* Interface_GUIControlButton::get_label2(void* kodiBase, void* handle)
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Button.h b/xbmc/addons/interfaces/gui/controls/Button.h
index c51600d23e..221ae4ea66 100644
--- a/xbmc/addons/interfaces/gui/controls/Button.h
+++ b/xbmc/addons/interfaces/gui/controls/Button.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/button.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,15 +42,15 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_enabled(void* kodiBase, void* handle, bool enabled);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_enabled(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
- static void set_label(void* kodiBase, void* handle, const char* label);
- static char* get_label(void* kodiBase, void* handle);
- static void set_label2(void* kodiBase, void* handle, const char* label);
- static char* get_label2(void* kodiBase, void* handle);
+ static void set_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ static char* get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_label2(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ static char* get_label2(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Edit.cpp b/xbmc/addons/interfaces/gui/controls/Edit.cpp
index 36dfe66370..b537279764 100644
--- a/xbmc/addons/interfaces/gui/controls/Edit.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Edit.cpp
@@ -14,14 +14,12 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlEdit::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_edit = static_cast<AddonToKodiFuncTable_kodi_gui_control_edit*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_edit)));
+ addonInterface->toKodi->kodi_gui->control_edit = new AddonToKodiFuncTable_kodi_gui_control_edit();
addonInterface->toKodi->kodi_gui->control_edit->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_edit->set_enabled = set_enabled;
@@ -36,45 +34,59 @@ void Interface_GUIControlEdit::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlEdit::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_edit);
+ delete addonInterface->toKodi->kodi_gui->control_edit;
}
-void Interface_GUIControlEdit::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlEdit::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlEdit::set_enabled(void* kodiBase, void* handle, bool enable)
+void Interface_GUIControlEdit::set_enabled(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool enable)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetEnabled(enable);
}
-void Interface_GUIControlEdit::set_input_type(void* kodiBase, void* handle, int type, const char *heading)
+void Interface_GUIControlEdit::set_input_type(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int type,
+ const char* heading)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control || !heading)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p', heading='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, heading, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "heading='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(heading),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -119,84 +131,105 @@ void Interface_GUIControlEdit::set_input_type(void* kodiBase, void* handle, int
control->SetInputType(kodiType, heading);
}
-void Interface_GUIControlEdit::set_label(void* kodiBase, void* handle, const char *label)
+void Interface_GUIControlEdit::set_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control || !label)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p', label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
control->SetLabel(label);
}
-char* Interface_GUIControlEdit::get_label(void* kodiBase, void* handle)
+char* Interface_GUIControlEdit::get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
return strdup(control->GetLabel().c_str());
}
-void Interface_GUIControlEdit::set_text(void* kodiBase, void* handle, const char* text)
+void Interface_GUIControlEdit::set_text(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control || !text)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p', text='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, text, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "text='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(text),
+ addon ? addon->ID() : "unknown");
return;
}
control->SetLabel2(text);
}
-char* Interface_GUIControlEdit::get_text(void* kodiBase, void* handle)
+char* Interface_GUIControlEdit::get_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
return strdup(control->GetLabel2().c_str());
}
-void Interface_GUIControlEdit::set_cursor_position(void* kodiBase, void* handle, unsigned int position)
+void Interface_GUIControlEdit::set_cursor_position(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ unsigned int position)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetCursorPosition(position);
}
-unsigned int Interface_GUIControlEdit::get_cursor_position(void* kodiBase, void* handle)
+unsigned int Interface_GUIControlEdit::get_cursor_position(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIEditControl* control = static_cast<CGUIEditControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlEdit::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlEdit::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return 0;
}
@@ -204,4 +237,3 @@ unsigned int Interface_GUIControlEdit::get_cursor_position(void* kodiBase, void*
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Edit.h b/xbmc/addons/interfaces/gui/controls/Edit.h
index b8eb717600..9dda1e2046 100644
--- a/xbmc/addons/interfaces/gui/controls/Edit.h
+++ b/xbmc/addons/interfaces/gui/controls/Edit.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/edit.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,21 +42,26 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_enabled(void* kodiBase, void* handle, bool enabled);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_enabled(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
- static void set_input_type(void* kodiBase, void* handle, int type, const char* heading);
+ static void set_input_type(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int type,
+ const char* heading);
- static void set_label(void* kodiBase, void* handle, const char* label);
- static char* get_label(void* kodiBase, void* handle);
+ static void set_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ static char* get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_text(void* kodiBase, void* handle, const char* text);
- static char* get_text(void* kodiBase, void* handle);
+ static void set_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ static char* get_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_cursor_position(void* kodiBase, void* handle, unsigned int position);
- static unsigned int get_cursor_position(void* kodiBase, void* handle);
+ static void set_cursor_position(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ unsigned int position);
+ static unsigned int get_cursor_position(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/FadeLabel.cpp b/xbmc/addons/interfaces/gui/controls/FadeLabel.cpp
index 7ad9f7de0b..13c560442c 100644
--- a/xbmc/addons/interfaces/gui/controls/FadeLabel.cpp
+++ b/xbmc/addons/interfaces/gui/controls/FadeLabel.cpp
@@ -14,14 +14,13 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlFadeLabel::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_fade_label = static_cast<AddonToKodiFuncTable_kodi_gui_control_fade_label*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_fade_label)));
+ addonInterface->toKodi->kodi_gui->control_fade_label =
+ new AddonToKodiFuncTable_kodi_gui_control_fade_label();
addonInterface->toKodi->kodi_gui->control_fade_label->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_fade_label->add_label = add_label;
@@ -32,31 +31,40 @@ void Interface_GUIControlFadeLabel::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlFadeLabel::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_fade_label);
+ delete addonInterface->toKodi->kodi_gui->control_fade_label;
}
-void Interface_GUIControlFadeLabel::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlFadeLabel::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIFadeLabelControl* control = static_cast<CGUIFadeLabelControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlFadeLabel::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlFadeLabel::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlFadeLabel::add_label(void* kodiBase, void* handle, const char *label)
+void Interface_GUIControlFadeLabel::add_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIFadeLabelControl* control = static_cast<CGUIFadeLabelControl*>(handle);
if (!addon || !control || !label)
{
- CLog::Log(LOGERROR, "Interface_GUIControlFadeLabel::%s - invalid handler data (kodiBase='%p', handle='%p', label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlFadeLabel::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}', label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -65,14 +73,16 @@ void Interface_GUIControlFadeLabel::add_label(void* kodiBase, void* handle, cons
control->OnMessage(msg);
}
-char* Interface_GUIControlFadeLabel::get_label(void* kodiBase, void* handle)
+char* Interface_GUIControlFadeLabel::get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIFadeLabelControl* control = static_cast<CGUIFadeLabelControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlFadeLabel::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlFadeLabel::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
@@ -82,28 +92,34 @@ char* Interface_GUIControlFadeLabel::get_label(void* kodiBase, void* handle)
return strdup(text.c_str());
}
-void Interface_GUIControlFadeLabel::set_scrolling(void* kodiBase, void* handle, bool scroll)
+void Interface_GUIControlFadeLabel::set_scrolling(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool scroll)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIFadeLabelControl* control = static_cast<CGUIFadeLabelControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlFadeLabel::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlFadeLabel::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetScrolling(scroll);
}
-void Interface_GUIControlFadeLabel::reset(void* kodiBase, void* handle)
+void Interface_GUIControlFadeLabel::reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIFadeLabelControl* control = static_cast<CGUIFadeLabelControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlFadeLabel::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlFadeLabel::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -112,4 +128,3 @@ void Interface_GUIControlFadeLabel::reset(void* kodiBase, void* handle)
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/FadeLabel.h b/xbmc/addons/interfaces/gui/controls/FadeLabel.h
index 967bea9ec2..2c3cd68037 100644
--- a/xbmc/addons/interfaces/gui/controls/FadeLabel.h
+++ b/xbmc/addons/interfaces/gui/controls/FadeLabel.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/fade_label.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,16 +42,16 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_enabled(void* kodiBase, void* handle, bool enabled);
- static void set_selected(void* kodiBase, void* handle, bool selected);
-
- static void add_label(void* kodiBase, void* handle, const char* label);
- static char* get_label(void* kodiBase, void* handle);
- static void set_scrolling(void* kodiBase, void* handle, bool scroll);
- static void reset(void* kodiBase, void* handle);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_enabled(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
+ static void set_selected(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool selected);
+
+ static void add_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ static char* get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_scrolling(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool scroll);
+ static void reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Image.cpp b/xbmc/addons/interfaces/gui/controls/Image.cpp
index a9303ba837..88f368c628 100644
--- a/xbmc/addons/interfaces/gui/controls/Image.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Image.cpp
@@ -15,14 +15,13 @@
using namespace KODI;
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlImage::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_image = static_cast<AddonToKodiFuncTable_kodi_gui_control_image*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_image)));
+ addonInterface->toKodi->kodi_gui->control_image =
+ new AddonToKodiFuncTable_kodi_gui_control_image();
addonInterface->toKodi->kodi_gui->control_image->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_image->set_filename = set_filename;
@@ -31,51 +30,59 @@ void Interface_GUIControlImage::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlImage::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_image);
+ delete addonInterface->toKodi->kodi_gui->control_image;
}
-void Interface_GUIControlImage::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlImage::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIImage* control = static_cast<CGUIImage*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlImage::%s - invalid handler data (kodiBase='%p', handle='%p') "
- "on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlImage::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlImage::set_filename(void* kodiBase, void* handle, const char* filename, bool use_cache)
+void Interface_GUIControlImage::set_filename(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* filename,
+ bool use_cache)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIImage* control = static_cast<CGUIImage*>(handle);
if (!addon || !control || !filename)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlImage::%s - invalid handler data (kodiBase='%p', handle='%p', "
- "filename='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, filename, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlImage::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "filename='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(filename),
+ addon ? addon->ID() : "unknown");
return;
}
control->SetFileName(filename, false, use_cache);
}
-void Interface_GUIControlImage::set_color_diffuse(void* kodiBase, void* handle, uint32_t colorDiffuse)
+void Interface_GUIControlImage::set_color_diffuse(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ uint32_t colorDiffuse)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIImage* control = static_cast<CGUIImage*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlImage::%s - invalid handler data (kodiBase='%p', handle='%p') "
- "on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlImage::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -83,4 +90,3 @@ void Interface_GUIControlImage::set_color_diffuse(void* kodiBase, void* handle,
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Image.h b/xbmc/addons/interfaces/gui/controls/Image.h
index 9dd0d47f54..b12becea30 100644
--- a/xbmc/addons/interfaces/gui/controls/Image.h
+++ b/xbmc/addons/interfaces/gui/controls/Image.h
@@ -8,15 +8,15 @@
#pragma once
-#include <stdint.h>
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/image.h"
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -42,11 +42,16 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_filename(void* kodiBase, void* handle, const char* filename, bool use_cache);
- static void set_color_diffuse(void* kodiBase, void* handle, uint32_t color_diffuse);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_filename(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* filename,
+ bool use_cache);
+ static void set_color_diffuse(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ uint32_t color_diffuse);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Label.cpp b/xbmc/addons/interfaces/gui/controls/Label.cpp
index 81ebbd904f..3922e3f815 100644
--- a/xbmc/addons/interfaces/gui/controls/Label.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Label.cpp
@@ -16,14 +16,13 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlLabel::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_label = static_cast<AddonToKodiFuncTable_kodi_gui_control_label*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_label)));
+ addonInterface->toKodi->kodi_gui->control_label =
+ new AddonToKodiFuncTable_kodi_gui_control_label();
addonInterface->toKodi->kodi_gui->control_label->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_label->set_label = set_label;
@@ -32,31 +31,40 @@ void Interface_GUIControlLabel::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlLabel::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_label);
+ delete addonInterface->toKodi->kodi_gui->control_label;
}
-void Interface_GUIControlLabel::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlLabel::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUILabelControl* control = static_cast<CGUILabelControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlLabel::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlLabel::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlLabel::set_label(void* kodiBase, void* handle, const char *label)
+void Interface_GUIControlLabel::set_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUILabelControl* control = static_cast<CGUILabelControl*>(handle);
if (!addon || !control || !label)
{
- CLog::Log(LOGERROR, "Interface_GUIControlLabel::%s - invalid handler data (kodiBase='%p', handle='%p', label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlLabel::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -65,14 +73,16 @@ void Interface_GUIControlLabel::set_label(void* kodiBase, void* handle, const ch
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-char* Interface_GUIControlLabel::get_label(void* kodiBase, void* handle)
+char* Interface_GUIControlLabel::get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUILabelControl* control = static_cast<CGUILabelControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlLabel::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlLabel::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
@@ -80,4 +90,3 @@ char* Interface_GUIControlLabel::get_label(void* kodiBase, void* handle)
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Label.h b/xbmc/addons/interfaces/gui/controls/Label.h
index ba2d2a1227..020c3d5d3e 100644
--- a/xbmc/addons/interfaces/gui/controls/Label.h
+++ b/xbmc/addons/interfaces/gui/controls/Label.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/label.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,12 +42,12 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
- static void set_label(void* kodiBase, void* handle, const char* label);
- static char* get_label(void* kodiBase, void* handle);
+ static void set_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ static char* get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Progress.cpp b/xbmc/addons/interfaces/gui/controls/Progress.cpp
index 17885c8ed1..639d079d4e 100644
--- a/xbmc/addons/interfaces/gui/controls/Progress.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Progress.cpp
@@ -14,14 +14,13 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlProgress::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_progress = static_cast<AddonToKodiFuncTable_kodi_gui_control_progress*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_progress)));
+ addonInterface->toKodi->kodi_gui->control_progress =
+ new AddonToKodiFuncTable_kodi_gui_control_progress();
addonInterface->toKodi->kodi_gui->control_progress->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_progress->set_percentage = set_percentage;
@@ -30,51 +29,56 @@ void Interface_GUIControlProgress::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlProgress::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_progress);
+ delete addonInterface->toKodi->kodi_gui->control_progress;
}
-void Interface_GUIControlProgress::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlProgress::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIProgressControl* control = static_cast<CGUIProgressControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlProgress::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlProgress::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlProgress::set_percentage(void* kodiBase, void* handle, float percent)
+void Interface_GUIControlProgress::set_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float percent)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIProgressControl* control = static_cast<CGUIProgressControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlProgress::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlProgress::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetPercentage(percent);
}
-float Interface_GUIControlProgress::get_percentage(void* kodiBase, void* handle)
+float Interface_GUIControlProgress::get_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIProgressControl* control = static_cast<CGUIProgressControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlProgress::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlProgress::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return 0.0f;
}
@@ -82,4 +86,3 @@ float Interface_GUIControlProgress::get_percentage(void* kodiBase, void* handle)
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Progress.h b/xbmc/addons/interfaces/gui/controls/Progress.h
index d701de76d5..c3368fa105 100644
--- a/xbmc/addons/interfaces/gui/controls/Progress.h
+++ b/xbmc/addons/interfaces/gui/controls/Progress.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/progress.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,12 +42,12 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
- static void set_percentage(void* kodiBase, void* handle, float percent);
- static float get_percentage(void* kodiBase, void* handle);
+ static void set_percentage(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float percent);
+ static float get_percentage(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/RadioButton.cpp b/xbmc/addons/interfaces/gui/controls/RadioButton.cpp
index 10b0d4e05f..9d3b82619b 100644
--- a/xbmc/addons/interfaces/gui/controls/RadioButton.cpp
+++ b/xbmc/addons/interfaces/gui/controls/RadioButton.cpp
@@ -13,14 +13,13 @@
#include "guilib/GUIRadioButtonControl.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlRadioButton::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_radio_button = static_cast<AddonToKodiFuncTable_kodi_gui_control_radio_button*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_radio_button)));
+ addonInterface->toKodi->kodi_gui->control_radio_button =
+ new AddonToKodiFuncTable_kodi_gui_control_radio_button();
addonInterface->toKodi->kodi_gui->control_radio_button->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_radio_button->set_enabled = set_enabled;
@@ -34,99 +33,110 @@ void Interface_GUIControlRadioButton::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlRadioButton::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_radio_button);
+ delete addonInterface->toKodi->kodi_gui->control_radio_button;
}
-void Interface_GUIControlRadioButton::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlRadioButton::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIRadioButtonControl* control = static_cast<CGUIRadioButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlRadioButton::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlRadioButton::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlRadioButton::set_enabled(void* kodiBase, void* handle, bool enabled)
+void Interface_GUIControlRadioButton::set_enabled(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool enabled)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIRadioButtonControl* control = static_cast<CGUIRadioButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlRadioButton::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlRadioButton::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetEnabled(enabled);
}
-void Interface_GUIControlRadioButton::set_label(void* kodiBase, void* handle, const char *label)
+void Interface_GUIControlRadioButton::set_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIRadioButtonControl* control = static_cast<CGUIRadioButtonControl*>(handle);
if (!addon || !control || !label)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlRadioButton::%s - invalid handler data (kodiBase='%p', "
- "handle='%p', label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlRadioButton::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}', label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
control->SetLabel(label);
}
-char* Interface_GUIControlRadioButton::get_label(void* kodiBase, void* handle)
+char* Interface_GUIControlRadioButton::get_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIRadioButtonControl* control = static_cast<CGUIRadioButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlRadioButton::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlRadioButton::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
return strdup(control->GetLabel().c_str());
}
-void Interface_GUIControlRadioButton::set_selected(void* kodiBase, void* handle, bool selected)
+void Interface_GUIControlRadioButton::set_selected(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool selected)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIRadioButtonControl* control = static_cast<CGUIRadioButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlRadioButton::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlRadioButton::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetSelected(selected);
}
-bool Interface_GUIControlRadioButton::is_selected(void* kodiBase, void* handle)
+bool Interface_GUIControlRadioButton::is_selected(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIRadioButtonControl* control = static_cast<CGUIRadioButtonControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlRadioButton::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlRadioButton::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return false;
}
@@ -134,4 +144,3 @@ bool Interface_GUIControlRadioButton::is_selected(void* kodiBase, void* handle)
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/RadioButton.h b/xbmc/addons/interfaces/gui/controls/RadioButton.h
index a01b1c57b7..dd7ed4e9e3 100644
--- a/xbmc/addons/interfaces/gui/controls/RadioButton.h
+++ b/xbmc/addons/interfaces/gui/controls/RadioButton.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/radio_button.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,16 +42,16 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_enabled(void* kodiBase, void* handle, bool enabled);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_enabled(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
- static void set_label(void* kodiBase, void* handle, const char* label);
- static char* get_label(void* kodiBase, void* handle);
+ static void set_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* label);
+ static char* get_label(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_selected(void* kodiBase, void* handle, bool selected);
- static bool is_selected(void* kodiBase, void* handle);
+ static void set_selected(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool selected);
+ static bool is_selected(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Rendering.cpp b/xbmc/addons/interfaces/gui/controls/Rendering.cpp
index 98f97d06e6..a26a27f9c3 100644
--- a/xbmc/addons/interfaces/gui/controls/Rendering.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Rendering.cpp
@@ -14,14 +14,13 @@
#include "guilib/GUIRenderingControl.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlAddonRendering::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_rendering = static_cast<AddonToKodiFuncTable_kodi_gui_control_rendering*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_rendering)));
+ addonInterface->toKodi->kodi_gui->control_rendering =
+ new AddonToKodiFuncTable_kodi_gui_control_rendering();
addonInterface->toKodi->kodi_gui->control_rendering->set_callbacks = set_callbacks;
addonInterface->toKodi->kodi_gui->control_rendering->destroy = destroy;
@@ -29,22 +28,26 @@ void Interface_GUIControlAddonRendering::Init(AddonGlobalInterface* addonInterfa
void Interface_GUIControlAddonRendering::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_rendering);
+ delete addonInterface->toKodi->kodi_gui->control_rendering;
}
void Interface_GUIControlAddonRendering::set_callbacks(
- void* kodiBase, void* handle, void* clienthandle,
- bool (*createCB)(void*,int,int,int,int,void*),
- void (*renderCB)(void*), void (*stopCB)(void*), bool (*dirtyCB)(void*))
+ 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))
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonRenderingControl* control = static_cast<CGUIAddonRenderingControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlAddonRendering::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlAddonRendering::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -60,16 +63,17 @@ void Interface_GUIControlAddonRendering::set_callbacks(
control->m_control->InitCallback(control);
}
-void Interface_GUIControlAddonRendering::destroy(void* kodiBase, void* handle)
+void Interface_GUIControlAddonRendering::destroy(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUIAddonRenderingControl* control = static_cast<CGUIAddonRenderingControl*>(handle);
if (!addon || !control)
{
CLog::Log(LOGERROR,
- "Interface_GUIControlAddonRendering::%s - invalid handler data (kodiBase='%p', "
- "handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ "Interface_GUIControlAddonRendering::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -79,7 +83,7 @@ void Interface_GUIControlAddonRendering::destroy(void* kodiBase, void* handle)
}
-CGUIAddonRenderingControl::CGUIAddonRenderingControl(CGUIRenderingControl *control)
+CGUIAddonRenderingControl::CGUIAddonRenderingControl(CGUIRenderingControl* control)
: CBCreate{nullptr},
CBRender{nullptr},
CBStop{nullptr},
@@ -91,7 +95,7 @@ CGUIAddonRenderingControl::CGUIAddonRenderingControl(CGUIRenderingControl *contr
{
}
-bool CGUIAddonRenderingControl::Create(int x, int y, int w, int h, void *device)
+bool CGUIAddonRenderingControl::Create(int x, int y, int w, int h, void* device)
{
if (CBCreate)
{
@@ -142,4 +146,3 @@ bool CGUIAddonRenderingControl::IsDirty()
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Rendering.h b/xbmc/addons/interfaces/gui/controls/Rendering.h
index fccf399f2b..dbd82d8602 100644
--- a/xbmc/addons/interfaces/gui/controls/Rendering.h
+++ b/xbmc/addons/interfaces/gui/controls/Rendering.h
@@ -8,6 +8,7 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/rendering.h"
#include "guilib/IRenderingCallback.h"
class CGUIRenderingControl;
@@ -15,10 +16,10 @@ class CGUIRenderingControl;
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
class CAddonDll;
@@ -46,50 +47,43 @@ namespace ADDON
* class.
*/
//@{
- static void set_callbacks(void* kodiBase,
- void* handle,
- void* clienthandle,
- bool (*createCB)(void*,int,int,int,int,void*),
- void (*renderCB)(void*),
- void (*stopCB)(void*),
- bool (*dirtyCB)(void*));
- static void destroy(void* kodiBase, void* handle);
+ static 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));
+ static void destroy(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
//@}
};
class CGUIAddonRenderingControl : public IRenderingCallback
{
- friend struct Interface_GUIControlAddonRendering;
+ friend struct Interface_GUIControlAddonRendering;
+
public:
- explicit CGUIAddonRenderingControl(CGUIRenderingControl *pControl);
+ explicit CGUIAddonRenderingControl(CGUIRenderingControl* pControl);
~CGUIAddonRenderingControl() override = default;
- bool Create(int x, int y, int w, int h, void *device) override;
+ bool Create(int x, int y, int w, int h, void* device) override;
void Render() override;
void Stop() override;
bool IsDirty() override;
virtual void Delete();
protected:
- bool (*CBCreate)
- (void* cbhdl,
- int x,
- int y,
- int w,
- int h,
- void *device);
- void (*CBRender)
- (void* cbhdl);
- void (*CBStop)
- (void* cbhdl);
- bool (*CBDirty)
- (void* cbhdl);
+ bool (*CBCreate)(KODI_GUI_CLIENT_HANDLE cbhdl, int x, int y, int w, int h, void* device);
+ void (*CBRender)(KODI_GUI_CLIENT_HANDLE cbhdl);
+ void (*CBStop)(KODI_GUI_CLIENT_HANDLE cbhdl);
+ bool (*CBDirty)(KODI_GUI_CLIENT_HANDLE cbhdl);
- void* m_clientHandle;
+ KODI_GUI_CLIENT_HANDLE m_clientHandle;
CAddonDll* m_addon;
CGUIRenderingControl* m_control;
int m_refCount;
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/SettingsSlider.cpp b/xbmc/addons/interfaces/gui/controls/SettingsSlider.cpp
index 8c7f03f5c1..c847a642dd 100644
--- a/xbmc/addons/interfaces/gui/controls/SettingsSlider.cpp
+++ b/xbmc/addons/interfaces/gui/controls/SettingsSlider.cpp
@@ -16,14 +16,13 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlSettingsSlider::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_settings_slider = static_cast<AddonToKodiFuncTable_kodi_gui_control_settings_slider*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_settings_slider)));
+ addonInterface->toKodi->kodi_gui->control_settings_slider =
+ new AddonToKodiFuncTable_kodi_gui_control_settings_slider();
addonInterface->toKodi->kodi_gui->control_settings_slider->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_settings_slider->set_enabled = set_enabled;
@@ -42,50 +41,64 @@ void Interface_GUIControlSettingsSlider::Init(AddonGlobalInterface* addonInterfa
addonInterface->toKodi->kodi_gui->control_settings_slider->set_float_range = set_float_range;
addonInterface->toKodi->kodi_gui->control_settings_slider->set_float_value = set_float_value;
addonInterface->toKodi->kodi_gui->control_settings_slider->get_float_value = get_float_value;
- addonInterface->toKodi->kodi_gui->control_settings_slider->set_float_interval = set_float_interval;
+ addonInterface->toKodi->kodi_gui->control_settings_slider->set_float_interval =
+ set_float_interval;
}
void Interface_GUIControlSettingsSlider::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_settings_slider);
+ delete addonInterface->toKodi->kodi_gui->control_settings_slider;
}
-void Interface_GUIControlSettingsSlider::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlSettingsSlider::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlSettingsSlider::set_enabled(void* kodiBase, void* handle, bool enabled)
+void Interface_GUIControlSettingsSlider::set_enabled(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool enabled)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetEnabled(enabled);
}
-void Interface_GUIControlSettingsSlider::set_text(void* kodiBase, void* handle, const char *text)
+void Interface_GUIControlSettingsSlider::set_text(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control || !text)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p', text='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, text, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}', text='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(text),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -94,14 +107,16 @@ void Interface_GUIControlSettingsSlider::set_text(void* kodiBase, void* handle,
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-void Interface_GUIControlSettingsSlider::reset(void* kodiBase, void* handle)
+void Interface_GUIControlSettingsSlider::reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -109,14 +124,19 @@ void Interface_GUIControlSettingsSlider::reset(void* kodiBase, void* handle)
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-void Interface_GUIControlSettingsSlider::set_int_range(void* kodiBase, void* handle, int start, int end)
+void Interface_GUIControlSettingsSlider::set_int_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int start,
+ int end)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -124,14 +144,18 @@ void Interface_GUIControlSettingsSlider::set_int_range(void* kodiBase, void* han
control->SetRange(start, end);
}
-void Interface_GUIControlSettingsSlider::set_int_value(void* kodiBase, void* handle, int value)
+void Interface_GUIControlSettingsSlider::set_int_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -139,42 +163,53 @@ void Interface_GUIControlSettingsSlider::set_int_value(void* kodiBase, void* han
control->SetIntValue(value);
}
-int Interface_GUIControlSettingsSlider::get_int_value(void* kodiBase, void* handle)
+int Interface_GUIControlSettingsSlider::get_int_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return -1;
}
return control->GetIntValue();
}
-void Interface_GUIControlSettingsSlider::set_int_interval(void* kodiBase, void* handle, int interval)
+void Interface_GUIControlSettingsSlider::set_int_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int interval)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetIntInterval(interval);
}
-void Interface_GUIControlSettingsSlider::set_percentage(void* kodiBase, void* handle, float percent)
+void Interface_GUIControlSettingsSlider::set_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float percent)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -182,28 +217,36 @@ void Interface_GUIControlSettingsSlider::set_percentage(void* kodiBase, void* ha
control->SetPercentage(percent);
}
-float Interface_GUIControlSettingsSlider::get_percentage(void* kodiBase, void* handle)
+float Interface_GUIControlSettingsSlider::get_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return 0.0f;
}
return control->GetPercentage();
}
-void Interface_GUIControlSettingsSlider::set_float_range(void* kodiBase, void* handle, float start, float end)
+void Interface_GUIControlSettingsSlider::set_float_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -211,14 +254,18 @@ void Interface_GUIControlSettingsSlider::set_float_range(void* kodiBase, void* h
control->SetFloatRange(start, end);
}
-void Interface_GUIControlSettingsSlider::set_float_value(void* kodiBase, void* handle, float value)
+void Interface_GUIControlSettingsSlider::set_float_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -226,28 +273,35 @@ void Interface_GUIControlSettingsSlider::set_float_value(void* kodiBase, void* h
control->SetFloatValue(value);
}
-float Interface_GUIControlSettingsSlider::get_float_value(void* kodiBase, void* handle)
+float Interface_GUIControlSettingsSlider::get_float_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return 0.0f;
}
return control->GetFloatValue();
}
-void Interface_GUIControlSettingsSlider::set_float_interval(void* kodiBase, void* handle, float interval)
+void Interface_GUIControlSettingsSlider::set_float_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISettingsSliderControl* control = static_cast<CGUISettingsSliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSettingsSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSettingsSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -255,4 +309,3 @@ void Interface_GUIControlSettingsSlider::set_float_interval(void* kodiBase, void
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/SettingsSlider.h b/xbmc/addons/interfaces/gui/controls/SettingsSlider.h
index 25cb10fd7a..425c27564f 100644
--- a/xbmc/addons/interfaces/gui/controls/SettingsSlider.h
+++ b/xbmc/addons/interfaces/gui/controls/SettingsSlider.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/settings_slider.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,26 +42,36 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_enabled(void* kodiBase, void* handle, bool enabled);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_enabled(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
- static void set_text(void* kodiBase, void* handle, const char* text);
- static void reset(void* kodiBase, void* handle);
+ static void set_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ static void reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_int_range(void* kodiBase, void* handle, int start, int end);
- static void set_int_value(void* kodiBase, void* handle, int value);
- static int get_int_value(void* kodiBase, void* handle);
- static void set_int_interval(void* kodiBase, void* handle, int interval);
+ static void set_int_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int start,
+ int end);
+ static void set_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int value);
+ static int get_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_int_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int interval);
- static void set_percentage(void* kodiBase, void* handle, float percent);
- static float get_percentage(void* kodiBase, void* handle);
+ static void set_percentage(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float percent);
+ static float get_percentage(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_float_range(void* kodiBase, void* handle, float start, float end);
- static void set_float_value(void* kodiBase, void* handle, float value);
- static float get_float_value(void* kodiBase, void* handle);
- static void set_float_interval(void* kodiBase, void* handle, float interval);
+ static void set_float_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end);
+ static void set_float_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float value);
+ static float get_float_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_float_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Slider.cpp b/xbmc/addons/interfaces/gui/controls/Slider.cpp
index 8fe5a92e7d..73502d87e0 100644
--- a/xbmc/addons/interfaces/gui/controls/Slider.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Slider.cpp
@@ -16,14 +16,13 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlSlider::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_slider = static_cast<AddonToKodiFuncTable_kodi_gui_control_slider*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_slider)));
+ addonInterface->toKodi->kodi_gui->control_slider =
+ new AddonToKodiFuncTable_kodi_gui_control_slider();
addonInterface->toKodi->kodi_gui->control_slider->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_slider->set_enabled = set_enabled;
@@ -47,45 +46,55 @@ void Interface_GUIControlSlider::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlSlider::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_slider);
+ delete addonInterface->toKodi->kodi_gui->control_slider;
}
-void Interface_GUIControlSlider::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlSlider::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlSlider::set_enabled(void* kodiBase, void* handle, bool enabled)
+void Interface_GUIControlSlider::set_enabled(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool enabled)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetEnabled(enabled);
}
-void Interface_GUIControlSlider::reset(void* kodiBase, void* handle)
+void Interface_GUIControlSlider::reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -93,28 +102,36 @@ void Interface_GUIControlSlider::reset(void* kodiBase, void* handle)
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-char* Interface_GUIControlSlider::get_description(void* kodiBase, void* handle)
+char* Interface_GUIControlSlider::get_description(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
return strdup(control->GetDescription().c_str());
}
-void Interface_GUIControlSlider::set_int_range(void* kodiBase, void* handle, int start, int end)
+void Interface_GUIControlSlider::set_int_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int start,
+ int end)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -122,14 +139,18 @@ void Interface_GUIControlSlider::set_int_range(void* kodiBase, void* handle, int
control->SetRange(start, end);
}
-void Interface_GUIControlSlider::set_int_value(void* kodiBase, void* handle, int value)
+void Interface_GUIControlSlider::set_int_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -137,42 +158,52 @@ void Interface_GUIControlSlider::set_int_value(void* kodiBase, void* handle, int
control->SetIntValue(value);
}
-int Interface_GUIControlSlider::get_int_value(void* kodiBase, void* handle)
+int Interface_GUIControlSlider::get_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return -1;
}
return control->GetIntValue();
}
-void Interface_GUIControlSlider::set_int_interval(void* kodiBase, void* handle, int interval)
+void Interface_GUIControlSlider::set_int_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int interval)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetIntInterval(interval);
}
-void Interface_GUIControlSlider::set_percentage(void* kodiBase, void* handle, float percent)
+void Interface_GUIControlSlider::set_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float percent)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -180,28 +211,36 @@ void Interface_GUIControlSlider::set_percentage(void* kodiBase, void* handle, fl
control->SetPercentage(percent);
}
-float Interface_GUIControlSlider::get_percentage(void* kodiBase, void* handle)
+float Interface_GUIControlSlider::get_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return 0.0f;
}
return control->GetPercentage();
}
-void Interface_GUIControlSlider::set_float_range(void* kodiBase, void* handle, float start, float end)
+void Interface_GUIControlSlider::set_float_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -209,14 +248,18 @@ void Interface_GUIControlSlider::set_float_range(void* kodiBase, void* handle, f
control->SetFloatRange(start, end);
}
-void Interface_GUIControlSlider::set_float_value(void* kodiBase, void* handle, float value)
+void Interface_GUIControlSlider::set_float_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -224,28 +267,35 @@ void Interface_GUIControlSlider::set_float_value(void* kodiBase, void* handle, f
control->SetFloatValue(value);
}
-float Interface_GUIControlSlider::get_float_value(void* kodiBase, void* handle)
+float Interface_GUIControlSlider::get_float_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return 0.0f;
}
return control->GetFloatValue();
}
-void Interface_GUIControlSlider::set_float_interval(void* kodiBase, void* handle, float interval)
+void Interface_GUIControlSlider::set_float_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISliderControl* control = static_cast<CGUISliderControl*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSlider::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSlider::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -253,4 +303,3 @@ void Interface_GUIControlSlider::set_float_interval(void* kodiBase, void* handle
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Slider.h b/xbmc/addons/interfaces/gui/controls/Slider.h
index 975a526170..30afbafadd 100644
--- a/xbmc/addons/interfaces/gui/controls/Slider.h
+++ b/xbmc/addons/interfaces/gui/controls/Slider.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/slider.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,27 +42,37 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_enabled(void* kodiBase, void* handle, bool enabled);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_enabled(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
- static void reset(void* kodiBase, void* handle);
+ static void reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static char* get_description(void* kodiBase, void* handle);
+ static char* get_description(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_int_range(void* kodiBase, void* handle, int start, int end);
- static void set_int_value(void* kodiBase, void* handle, int value);
- static int get_int_value(void* kodiBase, void* handle);
- static void set_int_interval(void* kodiBase, void* handle, int interval);
+ static void set_int_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int start,
+ int end);
+ static void set_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int value);
+ static int get_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_int_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int interval);
- static void set_percentage(void* kodiBase, void* handle, float percent);
- static float get_percentage(void* kodiBase, void* handle);
+ static void set_percentage(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float percent);
+ static float get_percentage(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_float_range(void* kodiBase, void* handle, float start, float end);
- static void set_float_value(void* kodiBase, void* handle, float value);
- static float get_float_value(void* kodiBase, void* handle);
- static void set_float_interval(void* kodiBase, void* handle, float interval);
+ static void set_float_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end);
+ static void set_float_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float value);
+ static float get_float_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_float_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Spin.cpp b/xbmc/addons/interfaces/gui/controls/Spin.cpp
index 8990bd57ea..b9eb6ea3fc 100644
--- a/xbmc/addons/interfaces/gui/controls/Spin.cpp
+++ b/xbmc/addons/interfaces/gui/controls/Spin.cpp
@@ -16,14 +16,12 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlSpin::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_spin = static_cast<AddonToKodiFuncTable_kodi_gui_control_spin*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_spin)));
+ addonInterface->toKodi->kodi_gui->control_spin = new AddonToKodiFuncTable_kodi_gui_control_spin();
addonInterface->toKodi->kodi_gui->control_spin->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_spin->set_enabled = set_enabled;
@@ -49,45 +47,58 @@ void Interface_GUIControlSpin::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlSpin::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_spin);
+ delete addonInterface->toKodi->kodi_gui->control_spin;
}
-void Interface_GUIControlSpin::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlSpin::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlSpin::set_enabled(void* kodiBase, void* handle, bool enabled)
+void Interface_GUIControlSpin::set_enabled(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool enabled)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetEnabled(enabled);
}
-void Interface_GUIControlSpin::set_text(void* kodiBase, void* handle, const char *text)
+void Interface_GUIControlSpin::set_text(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control || !text)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p', text='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, text, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "text='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(text),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -96,14 +107,16 @@ void Interface_GUIControlSpin::set_text(void* kodiBase, void* handle, const char
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-void Interface_GUIControlSpin::reset(void* kodiBase, void* handle)
+void Interface_GUIControlSpin::reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -111,168 +124,219 @@ void Interface_GUIControlSpin::reset(void* kodiBase, void* handle)
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-void Interface_GUIControlSpin::set_type(void* kodiBase, void* handle, int type)
+void Interface_GUIControlSpin::set_type(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int type)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetType(type);
}
-void Interface_GUIControlSpin::add_string_label(void* kodiBase, void* handle, const char* label, const char* value)
+void Interface_GUIControlSpin::add_string_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label,
+ const char* value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control || !label || !value)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p', label='%p', value='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, value, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}', value='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ static_cast<const void*>(value), addon ? addon->ID() : "unknown");
return;
}
control->AddLabel(std::string(label), std::string(value));
}
-void Interface_GUIControlSpin::set_string_value(void* kodiBase, void* handle, const char* value)
+void Interface_GUIControlSpin::set_string_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control || !value)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p', value='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, value, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "value='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(value),
+ addon ? addon->ID() : "unknown");
return;
}
control->SetStringValue(std::string(value));
}
-char* Interface_GUIControlSpin::get_string_value(void* kodiBase, void* handle)
+char* Interface_GUIControlSpin::get_string_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
return strdup(control->GetStringValue().c_str());
}
-void Interface_GUIControlSpin::add_int_label(void* kodiBase, void* handle, const char* label, int value)
+void Interface_GUIControlSpin::add_int_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label,
+ int value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control || !label)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p', label='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, label, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}', "
+ "label='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(label),
+ addon ? addon->ID() : "unknown");
return;
}
control->AddLabel(std::string(label), value);
}
-void Interface_GUIControlSpin::set_int_range(void* kodiBase, void* handle, int start, int end)
+void Interface_GUIControlSpin::set_int_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int start,
+ int end)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetRange(start, end);
}
-void Interface_GUIControlSpin::set_int_value(void* kodiBase, void* handle, int value)
+void Interface_GUIControlSpin::set_int_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetValue(value);
}
-int Interface_GUIControlSpin::get_int_value(void* kodiBase, void* handle)
+int Interface_GUIControlSpin::get_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return -1;
}
return control->GetValue();
}
-void Interface_GUIControlSpin::set_float_range(void* kodiBase, void* handle, float start, float end)
+void Interface_GUIControlSpin::set_float_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetFloatRange(start, end);
}
-void Interface_GUIControlSpin::set_float_value(void* kodiBase, void* handle, float value)
+void Interface_GUIControlSpin::set_float_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float value)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetFloatValue(value);
}
-float Interface_GUIControlSpin::get_float_value(void* kodiBase, void* handle)
+float Interface_GUIControlSpin::get_float_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return 0.0f;
}
return control->GetFloatValue();
}
-void Interface_GUIControlSpin::set_float_interval(void* kodiBase, void* handle, float interval)
+void Interface_GUIControlSpin::set_float_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUISpinControlEx* control = static_cast<CGUISpinControlEx*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlSpin::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlSpin::{} - invalid handler data (kodiBase='{}', handle='{}') "
+ "on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -280,4 +344,3 @@ void Interface_GUIControlSpin::set_float_interval(void* kodiBase, void* handle,
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/Spin.h b/xbmc/addons/interfaces/gui/controls/Spin.h
index 984b3c4108..1c7102ea44 100644
--- a/xbmc/addons/interfaces/gui/controls/Spin.h
+++ b/xbmc/addons/interfaces/gui/controls/Spin.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/spin.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,29 +42,45 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void set_enabled(void* kodiBase, void* handle, bool enabled);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void set_enabled(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool enabled);
- static void set_text(void* kodiBase, void* handle, const char *text);
- static void reset(void* kodiBase, void* handle);
- static void set_type(void* kodiBase, void* handle, int type);
+ static void set_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ static void reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_type(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int type);
- static void add_string_label(void* kodiBase, void* handle, const char* label, const char* value);
- static void add_int_label(void* kodiBase, void* handle, const char* label, int value);
+ static void add_string_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label,
+ const char* value);
+ static void add_int_label(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* label,
+ int value);
- static void set_string_value(void* kodiBase, void* handle, const char* value);
- static char* get_string_value(void* kodiBase, void* handle);
+ static void set_string_value(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* value);
+ static char* get_string_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_int_range(void* kodiBase, void* handle, int start, int end);
- static void set_int_value(void* kodiBase, void* handle, int value);
- static int get_int_value(void* kodiBase, void* handle);
+ static void set_int_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ int start,
+ int end);
+ static void set_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int value);
+ static int get_int_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
- static void set_float_range(void* kodiBase, void* handle, float start, float end);
- static void set_float_value(void* kodiBase, void* handle, float value);
- static float get_float_value(void* kodiBase, void* handle);
- static void set_float_interval(void* kodiBase, void* handle, float interval);
+ static void set_float_range(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float start,
+ float end);
+ static void set_float_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, float value);
+ static float get_float_value(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_float_interval(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ float interval);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/TextBox.cpp b/xbmc/addons/interfaces/gui/controls/TextBox.cpp
index 50aca8e77d..44c5f893d2 100644
--- a/xbmc/addons/interfaces/gui/controls/TextBox.cpp
+++ b/xbmc/addons/interfaces/gui/controls/TextBox.cpp
@@ -16,14 +16,13 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIControlTextBox::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->control_text_box = static_cast<AddonToKodiFuncTable_kodi_gui_control_text_box*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_control_text_box)));
+ addonInterface->toKodi->kodi_gui->control_text_box =
+ new AddonToKodiFuncTable_kodi_gui_control_text_box();
addonInterface->toKodi->kodi_gui->control_text_box->set_visible = set_visible;
addonInterface->toKodi->kodi_gui->control_text_box->reset = reset;
@@ -35,31 +34,37 @@ void Interface_GUIControlTextBox::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIControlTextBox::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->control_text_box);
+ delete addonInterface->toKodi->kodi_gui->control_text_box;
}
-void Interface_GUIControlTextBox::set_visible(void* kodiBase, void* handle, bool visible)
+void Interface_GUIControlTextBox::set_visible(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ bool visible)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUITextBox* control = static_cast<CGUITextBox*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlTextBox::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlTextBox::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->SetVisible(visible);
}
-void Interface_GUIControlTextBox::reset(void* kodiBase, void* handle)
+void Interface_GUIControlTextBox::reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUITextBox* control = static_cast<CGUITextBox*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlTextBox::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlTextBox::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -67,14 +72,19 @@ void Interface_GUIControlTextBox::reset(void* kodiBase, void* handle)
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-void Interface_GUIControlTextBox::set_text(void* kodiBase, void* handle, const char* text)
+void Interface_GUIControlTextBox::set_text(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUITextBox* control = static_cast<CGUITextBox*>(handle);
if (!addon || !control || !text)
{
- CLog::Log(LOGERROR, "Interface_GUIControlTextBox::%s - invalid handler data (kodiBase='%p', handle='%p', text='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, text, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlTextBox::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}', text='{}') on addon '{}'",
+ __func__, kodiBase, handle, static_cast<const void*>(text),
+ addon ? addon->ID() : "unknown");
return;
}
@@ -83,42 +93,51 @@ void Interface_GUIControlTextBox::set_text(void* kodiBase, void* handle, const c
CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(msg, control->GetParentID());
}
-char* Interface_GUIControlTextBox::get_text(void* kodiBase, void* handle)
+char* Interface_GUIControlTextBox::get_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUITextBox* control = static_cast<CGUITextBox*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlTextBox::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlTextBox::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return nullptr;
}
return strdup(control->GetDescription().c_str());
}
-void Interface_GUIControlTextBox::scroll(void* kodiBase, void* handle, unsigned int position)
+void Interface_GUIControlTextBox::scroll(KODI_HANDLE kodiBase,
+ KODI_GUI_CONTROL_HANDLE handle,
+ unsigned int position)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUITextBox* control = static_cast<CGUITextBox*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlTextBox::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlTextBox::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
control->Scroll(position);
}
-void Interface_GUIControlTextBox::set_auto_scrolling(void* kodiBase, void* handle, int delay, int time, int repeat)
+void Interface_GUIControlTextBox::set_auto_scrolling(
+ KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int delay, int time, int repeat)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
CGUITextBox* control = static_cast<CGUITextBox*>(handle);
if (!addon || !control)
{
- CLog::Log(LOGERROR, "Interface_GUIControlTextBox::%s - invalid handler data (kodiBase='%p', handle='%p') on addon '%s'",
- __FUNCTION__, kodiBase, handle, addon ? addon->ID().c_str() : "unknown");
+ CLog::Log(LOGERROR,
+ "Interface_GUIControlTextBox::{} - invalid handler data (kodiBase='{}', "
+ "handle='{}') on addon '{}'",
+ __func__, kodiBase, handle, addon ? addon->ID() : "unknown");
return;
}
@@ -126,4 +145,3 @@ void Interface_GUIControlTextBox::set_auto_scrolling(void* kodiBase, void* handl
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/controls/TextBox.h b/xbmc/addons/interfaces/gui/controls/TextBox.h
index 73e408e89f..09c2ff4e61 100644
--- a/xbmc/addons/interfaces/gui/controls/TextBox.h
+++ b/xbmc/addons/interfaces/gui/controls/TextBox.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/controls/text_box.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -41,14 +43,15 @@ namespace ADDON
* class.
*/
//@{
- static void set_visible(void* kodiBase, void* handle, bool visible);
- static void reset(void* kodiBase, void* handle);
- static void set_text(void* kodiBase, void* handle, const char* text);
- static char* get_text(void* kodiBase, void* handle);
- static void scroll(void* kodiBase, void* handle, unsigned int position);
- static void set_auto_scrolling(void* kodiBase, void* handle, int delay, int time, int repeat);
+ static void set_visible(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, bool visible);
+ static void reset(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void set_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, const char* text);
+ static char* get_text(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle);
+ static void scroll(KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, unsigned int position);
+ static void set_auto_scrolling(
+ KODI_HANDLE kodiBase, KODI_GUI_CONTROL_HANDLE handle, int delay, int time, int repeat);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/ContextMenu.cpp b/xbmc/addons/interfaces/gui/dialogs/ContextMenu.cpp
index 6de6c24706..e0e5684652 100644
--- a/xbmc/addons/interfaces/gui/dialogs/ContextMenu.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/ContextMenu.cpp
@@ -16,40 +16,44 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIDialogContextMenu::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogContextMenu = static_cast<AddonToKodiFuncTable_kodi_gui_dialogContextMenu*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogContextMenu)));
+ addonInterface->toKodi->kodi_gui->dialogContextMenu =
+ new AddonToKodiFuncTable_kodi_gui_dialogContextMenu();
addonInterface->toKodi->kodi_gui->dialogContextMenu->open = open;
}
void Interface_GUIDialogContextMenu::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogContextMenu);
+ delete addonInterface->toKodi->kodi_gui->dialogContextMenu;
}
-int Interface_GUIDialogContextMenu::open(void* kodiBase, const char *heading, const char *entries[], unsigned int size)
+int Interface_GUIDialogContextMenu::open(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entries[],
+ unsigned int size)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogContextMenu::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogContextMenu::{} - invalid data", __func__);
return -1;
}
- CGUIDialogContextMenu* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogContextMenu>(WINDOW_DIALOG_CONTEXT_MENU);
+ CGUIDialogContextMenu* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogContextMenu>(
+ WINDOW_DIALOG_CONTEXT_MENU);
if (!heading || !entries || !dialog)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogContextMenu::%s - invalid handler data (heading='%p', "
- "entries='%p', dialog='%p') on addon '%s'",
- __FUNCTION__, heading, static_cast<const void*>(entries), kodiBase,
- addon->ID().c_str());
+ "Interface_GUIDialogContextMenu::{} - invalid handler data (heading='{}', "
+ "entries='{}', dialog='{}') on addon '{}'",
+ __func__, static_cast<const void*>(heading), static_cast<const void*>(entries),
+ kodiBase, addon->ID());
return -1;
}
@@ -61,4 +65,3 @@ int Interface_GUIDialogContextMenu::open(void* kodiBase, const char *heading, co
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/ContextMenu.h b/xbmc/addons/interfaces/gui/dialogs/ContextMenu.h
index c34e1fdd53..7b41a28fbc 100644
--- a/xbmc/addons/interfaces/gui/dialogs/ContextMenu.h
+++ b/xbmc/addons/interfaces/gui/dialogs/ContextMenu.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/context_menu.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,9 +42,12 @@ namespace ADDON
* class.
*/
//@{
- static int open(void* kodiBase, const char *heading, const char *entries[], unsigned int size);
+ static int open(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entries[],
+ unsigned int size);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.cpp b/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.cpp
index 8014ade213..9e7f7a7e69 100644
--- a/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.cpp
@@ -16,16 +16,15 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIDialogExtendedProgress::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogExtendedProgress = static_cast<AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress)));
+ addonInterface->toKodi->kodi_gui->dialogExtendedProgress =
+ new AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress();
- addonInterface->toKodi->kodi_gui->dialogExtendedProgress->new_dialog = new_dialog;
+ addonInterface->toKodi->kodi_gui->dialogExtendedProgress->new_dialog = new_dialog;
addonInterface->toKodi->kodi_gui->dialogExtendedProgress->delete_dialog = delete_dialog;
addonInterface->toKodi->kodi_gui->dialogExtendedProgress->get_title = get_title;
addonInterface->toKodi->kodi_gui->dialogExtendedProgress->set_title = set_title;
@@ -40,26 +39,30 @@ void Interface_GUIDialogExtendedProgress::Init(AddonGlobalInterface* addonInterf
void Interface_GUIDialogExtendedProgress::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogExtendedProgress);
+ delete addonInterface->toKodi->kodi_gui->dialogExtendedProgress;
}
-void* Interface_GUIDialogExtendedProgress::new_dialog(void* kodiBase, const char *title)
+KODI_GUI_HANDLE Interface_GUIDialogExtendedProgress::new_dialog(KODI_HANDLE kodiBase,
+ const char* title)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return nullptr;
}
// setup the progress dialog
- CGUIDialogExtendedProgressBar* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogExtendedProgressBar>(WINDOW_DIALOG_EXT_PROGRESS);
+ CGUIDialogExtendedProgressBar* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogExtendedProgressBar>(
+ WINDOW_DIALOG_EXT_PROGRESS);
if (!title || !dialog)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid handler data (title='%p', "
- "dialog='%p') on addon '%s'",
- __FUNCTION__, title, static_cast<void*>(dialog), addon->ID().c_str());
+ "Interface_GUIDialogExtendedProgress::{} - invalid handler data (title='{}', "
+ "dialog='{}') on addon '{}'",
+ __func__, static_cast<const void*>(title), static_cast<void*>(dialog), addon->ID());
return nullptr;
}
@@ -67,207 +70,232 @@ void* Interface_GUIDialogExtendedProgress::new_dialog(void* kodiBase, const char
return dlgProgressHandle;
}
-void Interface_GUIDialogExtendedProgress::delete_dialog(void* kodiBase, void* handle)
+void Interface_GUIDialogExtendedProgress::delete_dialog(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return;
}
if (!handle)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid handler data (handle='%p') on addon '%s'", __FUNCTION__, handle, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogExtendedProgress::{} - invalid handler data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgressBarHandle*>(handle)->MarkFinished();
}
-char* Interface_GUIDialogExtendedProgress::get_title(void* kodiBase, void* handle)
+char* Interface_GUIDialogExtendedProgress::get_title(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return nullptr;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid handler data (handle='%p') on "
- "addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogExtendedProgress::{} - invalid handler data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return nullptr;
}
return strdup(static_cast<CGUIDialogProgressBarHandle*>(handle)->Title().c_str());
}
-void Interface_GUIDialogExtendedProgress::set_title(void* kodiBase, void* handle, const char *title)
+void Interface_GUIDialogExtendedProgress::set_title(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ const char* title)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return;
}
if (!handle || !title)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid handler data (handle='%p', "
- "title='%p') on addon '%s'",
- __FUNCTION__, handle, title, addon->ID().c_str());
+ "Interface_GUIDialogExtendedProgress::{} - invalid handler data (handle='{}', "
+ "title='{}') on addon '{}'",
+ __func__, handle, static_cast<const void*>(title), addon->ID());
return;
}
static_cast<CGUIDialogProgressBarHandle*>(handle)->SetTitle(title);
}
-char* Interface_GUIDialogExtendedProgress::get_text(void* kodiBase, void* handle)
+char* Interface_GUIDialogExtendedProgress::get_text(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return nullptr;
}
if (!handle)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid add-on data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogExtendedProgress::{} - invalid add-on data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return nullptr;
}
return strdup(static_cast<CGUIDialogProgressBarHandle*>(handle)->Text().c_str());
}
-void Interface_GUIDialogExtendedProgress::set_text(void* kodiBase, void* handle, const char *text)
+void Interface_GUIDialogExtendedProgress::set_text(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return;
}
if (!handle || !text)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid handler data (handle='%p', "
- "text='%p') on addon '%s'",
- __FUNCTION__, handle, text, addon->ID().c_str());
+ "Interface_GUIDialogExtendedProgress::{} - invalid handler data (handle='{}', "
+ "text='{}') on addon '{}'",
+ __func__, handle, static_cast<const void*>(text), addon->ID());
return;
}
static_cast<CGUIDialogProgressBarHandle*>(handle)->SetText(text);
}
-bool Interface_GUIDialogExtendedProgress::is_finished(void* kodiBase, void* handle)
+bool Interface_GUIDialogExtendedProgress::is_finished(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return false;
}
if (!handle)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid add-on data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogExtendedProgress::{} - invalid add-on data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return false;
}
return static_cast<CGUIDialogProgressBarHandle*>(handle)->IsFinished();
}
-void Interface_GUIDialogExtendedProgress::mark_finished(void* kodiBase, void* handle)
+void Interface_GUIDialogExtendedProgress::mark_finished(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return;
}
if (!handle)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid add-on data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogExtendedProgress::{} - invalid add-on data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgressBarHandle*>(handle)->MarkFinished();
}
-float Interface_GUIDialogExtendedProgress::get_percentage(void* kodiBase, void* handle)
+float Interface_GUIDialogExtendedProgress::get_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return 0.0f;
}
if (!handle)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid add-on data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogExtendedProgress::{} - invalid add-on data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return 0.0f;
}
return static_cast<CGUIDialogProgressBarHandle*>(handle)->Percentage();
}
-void Interface_GUIDialogExtendedProgress::set_percentage(void* kodiBase, void* handle, float percentage)
+void Interface_GUIDialogExtendedProgress::set_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ float percentage)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return;
}
if (!handle)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid add-on data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogExtendedProgress::{} - invalid add-on data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgressBarHandle*>(handle)->SetPercentage(percentage);
}
-void Interface_GUIDialogExtendedProgress::set_progress(void* kodiBase, void* handle, int currentItem, int itemCount)
+void Interface_GUIDialogExtendedProgress::set_progress(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ int currentItem,
+ int itemCount)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::%s - invalid kodi base data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogExtendedProgress::{} - invalid kodi base data",
+ __func__);
return;
}
if (!handle)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogExtendedProgress::%s - invalid add-on data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogExtendedProgress::{} - invalid add-on data (handle='{}') on "
+ "addon '{}'",
+ __func__, handle, addon->ID());
return;
}
@@ -275,4 +303,3 @@ void Interface_GUIDialogExtendedProgress::set_progress(void* kodiBase, void* han
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.h b/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.h
index 0589a52dcf..66ccb49e6b 100644
--- a/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.h
+++ b/xbmc/addons/interfaces/gui/dialogs/ExtendedProgressBar.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/extended_progress.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,19 +42,22 @@ namespace ADDON
* class.
*/
//@{
- static void* new_dialog(void* kodiBase, const char* title);
- static void delete_dialog(void* kodiBase, void* handle);
- static char* get_title(void* kodiBase, void* handle);
- static void set_title(void* kodiBase, void* handle, const char* title);
- static char* get_text(void* kodiBase, void* handle);
- static void set_text(void* kodiBase, void* handle, const char* text);
- static bool is_finished(void* kodiBase, void* handle);
- static void mark_finished(void* kodiBase, void* handle);
- static float get_percentage(void* kodiBase, void* handle);
- static void set_percentage(void* kodiBase, void* handle, float percentage);
- static void set_progress(void* kodiBase, void* handle, int currentItem, int itemCount);
+ static KODI_GUI_HANDLE new_dialog(KODI_HANDLE kodiBase, const char* title);
+ static void delete_dialog(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static char* get_title(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void set_title(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, const char* title);
+ static char* get_text(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void set_text(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, const char* text);
+ static bool is_finished(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void mark_finished(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static float get_percentage(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void set_percentage(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, float percentage);
+ static void set_progress(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ int currentItem,
+ int itemCount);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/FileBrowser.cpp b/xbmc/addons/interfaces/gui/dialogs/FileBrowser.cpp
index b7d8d5f762..84d6443232 100644
--- a/xbmc/addons/interfaces/gui/dialogs/FileBrowser.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/FileBrowser.cpp
@@ -17,47 +17,54 @@
#include "utils/URIUtils.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIDialogFileBrowser::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogFileBrowser = static_cast<AddonToKodiFuncTable_kodi_gui_dialogFileBrowser*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogFileBrowser)));
+ addonInterface->toKodi->kodi_gui->dialogFileBrowser =
+ new AddonToKodiFuncTable_kodi_gui_dialogFileBrowser();
- addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_directory = show_and_get_directory;
+ addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_directory =
+ show_and_get_directory;
addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file = show_and_get_file;
- addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_from_dir = show_and_get_file_from_dir;
- addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_list = show_and_get_file_list;
+ addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_from_dir =
+ show_and_get_file_from_dir;
+ addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_list =
+ show_and_get_file_list;
addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_source = show_and_get_source;
addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image = show_and_get_image;
- addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image_list = show_and_get_image_list;
+ addonInterface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image_list =
+ show_and_get_image_list;
addonInterface->toKodi->kodi_gui->dialogFileBrowser->clear_file_list = clear_file_list;
}
void Interface_GUIDialogFileBrowser::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogFileBrowser);
+ delete addonInterface->toKodi->kodi_gui->dialogFileBrowser;
}
-bool Interface_GUIDialogFileBrowser::show_and_get_directory(void* kodiBase, const char* shares, const char* heading,
- const char* path_in, char** path_out, bool write_only)
+bool Interface_GUIDialogFileBrowser::show_and_get_directory(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ const char* path_in,
+ char** path_out,
+ bool write_only)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return false;
}
if (!shares || !heading || !path_in || !path_out)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (shares='%p', "
- "heading='%p', path_in='%p', path_out='%p') on addon '%s'",
- __FUNCTION__, shares, heading, path_in, static_cast<void*>(path_out),
- addon->ID().c_str());
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (shares='{}', "
+ "heading='{}', path_in='{}', path_out='{}') on addon '{}'",
+ __func__, static_cast<const void*>(shares), static_cast<const void*>(heading),
+ static_cast<const void*>(path_in), static_cast<void*>(path_out), addon->ID());
return false;
}
@@ -71,23 +78,30 @@ bool Interface_GUIDialogFileBrowser::show_and_get_directory(void* kodiBase, cons
return bRet;
}
-bool Interface_GUIDialogFileBrowser::show_and_get_file(void* 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 Interface_GUIDialogFileBrowser::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)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return false;
}
if (!shares || !mask || !heading || !path_in || !path_out)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (shares='%p', mask='%p', "
- "heading='%p', path_in='%p', path_out='%p') on addon '%s'",
- __FUNCTION__, shares, mask, heading, path_in, static_cast<void*>(path_out),
- addon->ID().c_str());
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (shares='{}', mask='{}', "
+ "heading='{}', path_in='{}', path_out='{}') on addon '{}'",
+ __func__, static_cast<const void*>(shares), static_cast<const void*>(mask),
+ static_cast<const void*>(heading), static_cast<const void*>(path_in),
+ static_cast<void*>(path_out), addon->ID());
return false;
}
@@ -95,58 +109,73 @@ bool Interface_GUIDialogFileBrowser::show_and_get_file(void* kodiBase, const cha
VECSOURCES vecShares;
GetVECShares(vecShares, shares, strPath);
- bool bRet = CGUIDialogFileBrowser::ShowAndGetFile(vecShares, mask, heading, strPath, use_thumbs, use_file_directories);
+ bool bRet = CGUIDialogFileBrowser::ShowAndGetFile(vecShares, mask, heading, strPath, use_thumbs,
+ use_file_directories);
if (bRet)
*path_out = strdup(strPath.c_str());
return bRet;
}
-bool Interface_GUIDialogFileBrowser::show_and_get_file_from_dir(void* 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 single_list)
+bool Interface_GUIDialogFileBrowser::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 single_list)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return false;
}
if (!directory || !mask || !heading || !path_in || !path_out)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (directory='%p', "
- "mask='%p', heading='%p', path_in='%p', path_out='%p') on addon '%s'",
- __FUNCTION__, directory, mask, heading, path_in, static_cast<void*>(path_out),
- addon->ID().c_str());
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (directory='{}', "
+ "mask='{}', heading='{}', path_in='{}', path_out='{}') on addon '{}'",
+ __func__, static_cast<const void*>(directory), static_cast<const void*>(mask),
+ static_cast<const void*>(heading), static_cast<const void*>(path_in),
+ static_cast<void*>(path_out), addon->ID());
return false;
}
std::string strPath = path_in;
- bool bRet = CGUIDialogFileBrowser::ShowAndGetFile(directory, mask, heading, strPath, use_thumbs, use_file_directories, single_list);
+ bool bRet = CGUIDialogFileBrowser::ShowAndGetFile(directory, mask, heading, strPath, use_thumbs,
+ use_file_directories, single_list);
if (bRet)
*path_out = strdup(strPath.c_str());
return bRet;
}
-bool Interface_GUIDialogFileBrowser::show_and_get_file_list(void* kodiBase, const char* shares, const char* mask,
- const char* heading, char*** file_list, unsigned int* entries,
- bool use_thumbs, bool use_file_directories)
+bool Interface_GUIDialogFileBrowser::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)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return false;
}
if (!shares || !mask || !heading || !file_list || !entries)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (shares='%p', mask='%p', "
- "heading='%p', file_list='%p', entries='%p') on addon '%s'",
- __FUNCTION__, shares, mask, heading, static_cast<void*>(file_list),
- static_cast<void*>(entries), addon->ID().c_str());
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (shares='{}', mask='{}', "
+ "heading='{}', file_list='{}', entries='{}') on addon '{}'",
+ __func__, static_cast<const void*>(shares), static_cast<const void*>(mask),
+ static_cast<const void*>(heading), static_cast<void*>(file_list),
+ static_cast<void*>(entries), addon->ID());
return false;
}
@@ -154,11 +183,12 @@ bool Interface_GUIDialogFileBrowser::show_and_get_file_list(void* kodiBase, cons
GetVECShares(vecShares, shares, "");
std::vector<std::string> pathsInt;
- bool bRet = CGUIDialogFileBrowser::ShowAndGetFileList(vecShares, mask, heading, pathsInt, use_thumbs, use_file_directories);
+ bool bRet = CGUIDialogFileBrowser::ShowAndGetFileList(vecShares, mask, heading, pathsInt,
+ use_thumbs, use_file_directories);
if (bRet)
{
*entries = pathsInt.size();
- *file_list = static_cast<char**>(malloc(*entries*sizeof(char*)));
+ *file_list = static_cast<char**>(malloc(*entries * sizeof(char*)));
for (unsigned int i = 0; i < *entries; ++i)
(*file_list)[i] = strdup(pathsInt[i].c_str());
}
@@ -167,24 +197,28 @@ bool Interface_GUIDialogFileBrowser::show_and_get_file_list(void* kodiBase, cons
return bRet;
}
-bool Interface_GUIDialogFileBrowser::show_and_get_source(void* kodiBase, const char* path_in, char** path_out,
- bool allowNetworkShares, const char* additionalShare,
+bool Interface_GUIDialogFileBrowser::show_and_get_source(KODI_HANDLE kodiBase,
+ const char* path_in,
+ char** path_out,
+ bool allowNetworkShares,
+ const char* additionalShare,
const char* strType)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return false;
}
if (!strType || !additionalShare || !path_in || !path_out)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (additionalShare='%p', "
- "strType='%p', path_in='%p', path_out='%p') on addon '%s'",
- __FUNCTION__, additionalShare, strType, path_in, static_cast<void*>(path_out),
- addon->ID().c_str());
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (additionalShare='{}', "
+ "strType='{}', path_in='{}', path_out='{}') on addon '{}'",
+ __func__, static_cast<const void*>(additionalShare),
+ static_cast<const void*>(strType), static_cast<const void*>(path_in),
+ static_cast<void*>(path_out), addon->ID());
return false;
}
@@ -193,28 +227,33 @@ bool Interface_GUIDialogFileBrowser::show_and_get_source(void* kodiBase, const c
VECSOURCES vecShares;
if (additionalShare)
GetVECShares(vecShares, additionalShare, strPath);
- bool bRet = CGUIDialogFileBrowser::ShowAndGetSource(strPath, allowNetworkShares, &vecShares, strType);
+ bool bRet =
+ CGUIDialogFileBrowser::ShowAndGetSource(strPath, allowNetworkShares, &vecShares, strType);
if (bRet)
*path_out = strdup(strPath.c_str());
return bRet;
}
-bool Interface_GUIDialogFileBrowser::show_and_get_image(void* kodiBase, const char* shares, const char* heading,
- const char* path_in, char** path_out)
+bool Interface_GUIDialogFileBrowser::show_and_get_image(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ const char* path_in,
+ char** path_out)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return false;
}
if (!shares || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (shares='%p', "
- "heading='%p') on addon '%s'",
- __FUNCTION__, shares, heading, addon->ID().c_str());
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (shares='{}', "
+ "heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(shares), static_cast<const void*>(heading),
+ addon->ID());
return false;
}
@@ -228,23 +267,26 @@ bool Interface_GUIDialogFileBrowser::show_and_get_image(void* kodiBase, const ch
return bRet;
}
-bool Interface_GUIDialogFileBrowser::show_and_get_image_list(void* kodiBase, const char* shares, const char* heading, char*** file_list, unsigned int* entries)
+bool Interface_GUIDialogFileBrowser::show_and_get_image_list(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ char*** file_list,
+ unsigned int* entries)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return false;
}
if (!shares || !heading || !file_list || !entries)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (shares='%p', "
- "heading='%p', file_list='%p', entries='%p') on addon '%s'",
- __FUNCTION__, shares, heading,
- static_cast<void*>(file_list), static_cast<void*>(entries),
- addon->ID().c_str());
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (shares='{}', "
+ "heading='{}', file_list='{}', entries='{}') on addon '{}'",
+ __func__, static_cast<const void*>(shares), static_cast<const void*>(heading),
+ static_cast<void*>(file_list), static_cast<void*>(entries), addon->ID());
return false;
}
@@ -256,7 +298,7 @@ bool Interface_GUIDialogFileBrowser::show_and_get_image_list(void* kodiBase, con
if (bRet)
{
*entries = pathsInt.size();
- *file_list = static_cast<char**>(malloc(*entries*sizeof(char*)));
+ *file_list = static_cast<char**>(malloc(*entries * sizeof(char*)));
for (unsigned int i = 0; i < *entries; ++i)
(*file_list)[i] = strdup(pathsInt[i].c_str());
}
@@ -265,12 +307,14 @@ bool Interface_GUIDialogFileBrowser::show_and_get_image_list(void* kodiBase, con
return bRet;
}
-void Interface_GUIDialogFileBrowser::clear_file_list(void* kodiBase, char*** file_list, unsigned int entries)
+void Interface_GUIDialogFileBrowser::clear_file_list(KODI_HANDLE kodiBase,
+ char*** file_list,
+ unsigned int entries)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogFileBrowser::{} - invalid data", __func__);
return;
}
@@ -284,55 +328,57 @@ void Interface_GUIDialogFileBrowser::clear_file_list(void* kodiBase, char*** fil
else
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogFileBrowser::%s - invalid handler data (file_list='%p') on addon '%s'",
- __FUNCTION__, static_cast<void*>(file_list), addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogFileBrowser::{} - invalid handler data (file_list='{}') on "
+ "addon '{}'",
+ __func__, static_cast<void*>(file_list), addon->ID());
}
}
-void Interface_GUIDialogFileBrowser::GetVECShares(VECSOURCES& vecShares, const std::string& strShares, const std::string& strPath)
+void Interface_GUIDialogFileBrowser::GetVECShares(VECSOURCES& vecShares,
+ const std::string& strShares,
+ const std::string& strPath)
{
std::size_t found;
found = strShares.find("local");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
CServiceBroker::GetMediaManager().GetLocalDrives(vecShares);
found = strShares.find("network");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
CServiceBroker::GetMediaManager().GetNetworkLocations(vecShares);
found = strShares.find("removable");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
CServiceBroker::GetMediaManager().GetRemovableDrives(vecShares);
found = strShares.find("programs");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
{
VECSOURCES* sources = CMediaSourceSettings::GetInstance().GetSources("programs");
if (sources != nullptr)
vecShares.insert(vecShares.end(), sources->begin(), sources->end());
}
found = strShares.find("files");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
{
VECSOURCES* sources = CMediaSourceSettings::GetInstance().GetSources("files");
if (sources != nullptr)
vecShares.insert(vecShares.end(), sources->begin(), sources->end());
}
found = strShares.find("music");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
{
VECSOURCES* sources = CMediaSourceSettings::GetInstance().GetSources("music");
if (sources != nullptr)
vecShares.insert(vecShares.end(), sources->begin(), sources->end());
}
found = strShares.find("video");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
{
VECSOURCES* sources = CMediaSourceSettings::GetInstance().GetSources("video");
if (sources != nullptr)
vecShares.insert(vecShares.end(), sources->begin(), sources->end());
}
found = strShares.find("pictures");
- if (found!=std::string::npos)
+ if (found != std::string::npos)
{
VECSOURCES* sources = CMediaSourceSettings::GetInstance().GetSources("pictures");
if (sources != nullptr)
@@ -355,4 +401,3 @@ void Interface_GUIDialogFileBrowser::GetVECShares(VECSOURCES& vecShares, const s
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/FileBrowser.h b/xbmc/addons/interfaces/gui/dialogs/FileBrowser.h
index 89a63521d0..c2193f3f72 100644
--- a/xbmc/addons/interfaces/gui/dialogs/FileBrowser.h
+++ b/xbmc/addons/interfaces/gui/dialogs/FileBrowser.h
@@ -8,6 +8,8 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/filebrowser.h"
+
#include <string>
#include <vector>
@@ -18,10 +20,10 @@ typedef std::vector<CMediaSource> VECSOURCES;
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -47,43 +49,68 @@ namespace ADDON
* class.
*/
//@{
- static bool show_and_get_directory(void* kodiBase, const char* shares,
- const char* heading, const char* path_in,
- char** path_out, bool write_only);
-
- static bool show_and_get_file(void* kodiBase, const char* shares,
- const char* mask, const char* heading,
- const char* path_in, char** path_out,
- bool use_thumbs, bool use_file_directories);
-
- static bool show_and_get_file_from_dir(void* kodiBase, const char* directory,
- const char* mask, const char* heading,
- const char* path_in, char** path_out,
- bool use_thumbs, bool use_file_directories,
+ static bool show_and_get_directory(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ const char* path_in,
+ char** path_out,
+ bool write_only);
+
+ static 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);
+
+ static 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);
- static bool show_and_get_file_list(void* kodiBase, const char* shares,
- const char* mask, const char* heading,
- char*** file_list, unsigned int* entries,
- bool use_thumbs, bool use_file_directories);
-
- static bool show_and_get_source(void* kodiBase, const char* path_in, char** path_out,
- bool allow_network_shares, const char* additional_share,
+ static 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);
+
+ static 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);
- static bool show_and_get_image(void* kodiBase, const char* shares, const char* heading,
- const char* path_in, char** path_out);
+ static bool show_and_get_image(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ const char* path_in,
+ char** path_out);
- static bool show_and_get_image_list(void* kodiBase, const char* shares,
- const char* heading, char*** file_list,
+ static bool show_and_get_image_list(KODI_HANDLE kodiBase,
+ const char* shares,
+ const char* heading,
+ char*** file_list,
unsigned int* entries);
- static void clear_file_list(void* kodiBase, char*** file_list, unsigned int entries);
+ static void clear_file_list(KODI_HANDLE kodiBase, char*** file_list, unsigned int entries);
//@}
private:
- static void GetVECShares(VECSOURCES& vecShares, const std::string& strShares, const std::string& strPath);
+ static void GetVECShares(VECSOURCES& vecShares,
+ const std::string& strShares,
+ const std::string& strPath);
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Keyboard.cpp b/xbmc/addons/interfaces/gui/dialogs/Keyboard.cpp
index 8b375434c9..7ec56ab18b 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Keyboard.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/Keyboard.cpp
@@ -16,72 +16,89 @@
namespace ADDON
{
-extern "C"
-{
void Interface_GUIDialogKeyboard::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogKeyboard = static_cast<AddonToKodiFuncTable_kodi_gui_dialogKeyboard*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogKeyboard)));
+ addonInterface->toKodi->kodi_gui->dialogKeyboard =
+ new AddonToKodiFuncTable_kodi_gui_dialogKeyboard();
- addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input_with_head = show_and_get_input_with_head;
+ addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input_with_head =
+ show_and_get_input_with_head;
addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input = show_and_get_input;
- addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password_with_head = show_and_get_new_password_with_head;
- addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password = show_and_get_new_password;
- addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password_with_head = show_and_verify_new_password_with_head;
- addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password = show_and_verify_new_password;
- addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_password = show_and_verify_password;
+ addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password_with_head =
+ show_and_get_new_password_with_head;
+ addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password =
+ show_and_get_new_password;
+ addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password_with_head =
+ show_and_verify_new_password_with_head;
+ addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password =
+ show_and_verify_new_password;
+ addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_password =
+ show_and_verify_password;
addonInterface->toKodi->kodi_gui->dialogKeyboard->show_and_get_filter = show_and_get_filter;
- addonInterface->toKodi->kodi_gui->dialogKeyboard->send_text_to_active_keyboard = send_text_to_active_keyboard;
+ addonInterface->toKodi->kodi_gui->dialogKeyboard->send_text_to_active_keyboard =
+ send_text_to_active_keyboard;
addonInterface->toKodi->kodi_gui->dialogKeyboard->is_keyboard_activated = is_keyboard_activated;
}
void Interface_GUIDialogKeyboard::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogKeyboard);
+ delete addonInterface->toKodi->kodi_gui->dialogKeyboard;
}
-bool Interface_GUIDialogKeyboard::show_and_get_input_with_head(void* kodiBase, const char* text_in, char** text_out,
- const char* heading, bool allow_empty_result,
- bool hidden_input, unsigned int auto_close_ms)
+bool Interface_GUIDialogKeyboard::show_and_get_input_with_head(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ const char* heading,
+ bool allow_empty_result,
+ bool hidden_input,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!text_in || !text_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (text_in='%p', "
- "text_out='%p', heading='%p') on addon '%s'",
- __FUNCTION__, text_in, static_cast<void*>(text_out), heading, addon->ID().c_str());
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (text_in='{}', "
+ "text_out='{}', heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(text_in), static_cast<void*>(text_out),
+ static_cast<const void*>(heading), addon->ID());
return false;
}
std::string str = text_in;
- bool bRet = CGUIKeyboardFactory::ShowAndGetInput(str, CVariant{heading}, allow_empty_result, hidden_input, auto_close_ms);
+ bool bRet = CGUIKeyboardFactory::ShowAndGetInput(str, CVariant{heading}, allow_empty_result,
+ hidden_input, auto_close_ms);
if (bRet)
*text_out = strdup(str.c_str());
return bRet;
}
-bool Interface_GUIDialogKeyboard::show_and_get_input(void* kodiBase, const char* text_in, char** text_out, bool allow_empty_result, unsigned int auto_close_ms)
+bool Interface_GUIDialogKeyboard::show_and_get_input(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ bool allow_empty_result,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!text_in || !text_out)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (text_in='%p', "
- "text_out='%p') on addon '%s'",
- __FUNCTION__, text_in, static_cast<void*>(text_out), addon->ID().c_str());
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (text_in='{}', "
+ "text_out='{}') on addon '{}'",
+ __func__, static_cast<const void*>(text_in), static_cast<void*>(text_out),
+ addon->ID());
return false;
}
@@ -92,48 +109,57 @@ bool Interface_GUIDialogKeyboard::show_and_get_input(void* kodiBase, const char*
return bRet;
}
-bool Interface_GUIDialogKeyboard::show_and_get_new_password_with_head(void* kodiBase, const char* password_in, char** password_out,
- const char* heading, bool allow_empty_result, unsigned int auto_close_ms)
+bool Interface_GUIDialogKeyboard::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)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!password_in || !password_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (password_in='%p', "
- "password_out='%p', heading='%p') on addon '%s'",
- __FUNCTION__, password_in, static_cast<void*>(password_out), heading,
- addon->ID().c_str());
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (password_in='{}', "
+ "password_out='{}', heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(password_in), static_cast<void*>(password_out),
+ static_cast<const void*>(heading), addon->ID());
return false;
}
std::string str = password_in;
- bool bRet = CGUIKeyboardFactory::ShowAndGetNewPassword(str, heading, allow_empty_result, auto_close_ms);
+ bool bRet =
+ CGUIKeyboardFactory::ShowAndGetNewPassword(str, heading, allow_empty_result, auto_close_ms);
if (bRet)
*password_out = strdup(str.c_str());
return bRet;
}
-bool Interface_GUIDialogKeyboard::show_and_get_new_password(void* kodiBase, const char* password_in, char** password_out, unsigned int auto_close_ms)
+bool Interface_GUIDialogKeyboard::show_and_get_new_password(KODI_HANDLE kodiBase,
+ const char* password_in,
+ char** password_out,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!password_in || !password_out)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (password_in='%p', "
- "password_out='%p') on addon '%s'",
- __FUNCTION__, password_in, static_cast<void*>(password_out), addon->ID().c_str());
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (password_in='{}', "
+ "password_out='{}') on addon '{}'",
+ __func__, static_cast<const void*>(password_in), static_cast<void*>(password_out),
+ addon->ID());
return false;
}
@@ -144,47 +170,54 @@ bool Interface_GUIDialogKeyboard::show_and_get_new_password(void* kodiBase, cons
return bRet;
}
-bool Interface_GUIDialogKeyboard::show_and_verify_new_password_with_head(void* kodiBase, char** password_out, const char* heading,
- bool allowEmpty, unsigned int auto_close_ms)
+bool Interface_GUIDialogKeyboard::show_and_verify_new_password_with_head(KODI_HANDLE kodiBase,
+ char** password_out,
+ const char* heading,
+ bool allowEmpty,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!password_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (password_out='%p', "
- "heading='%p') on addon '%s'",
- __FUNCTION__, static_cast<void*>(password_out), heading, addon->ID().c_str());
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (password_out='{}', "
+ "heading='{}') on addon '{}'",
+ __func__, static_cast<void*>(password_out), static_cast<const void*>(heading),
+ addon->ID());
return false;
}
std::string str;
- bool bRet = CGUIKeyboardFactory::ShowAndVerifyNewPassword(str, heading, allowEmpty, auto_close_ms);
+ bool bRet =
+ CGUIKeyboardFactory::ShowAndVerifyNewPassword(str, heading, allowEmpty, auto_close_ms);
if (bRet)
*password_out = strdup(str.c_str());
return bRet;
}
-bool Interface_GUIDialogKeyboard::show_and_verify_new_password(void* kodiBase, char** password_out, unsigned int auto_close_ms)
+bool Interface_GUIDialogKeyboard::show_and_verify_new_password(KODI_HANDLE kodiBase,
+ char** password_out,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!password_out)
{
- CLog::Log(
- LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (password_out='%p') on addon '%s'",
- __FUNCTION__, static_cast<void*>(password_out), addon->ID().c_str());
+ CLog::Log(LOGERROR,
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (password_out='{}') on "
+ "addon '{}'",
+ __func__, static_cast<void*>(password_out), addon->ID());
return false;
}
@@ -195,22 +228,27 @@ bool Interface_GUIDialogKeyboard::show_and_verify_new_password(void* kodiBase, c
return bRet;
}
-int Interface_GUIDialogKeyboard::show_and_verify_password(void* kodiBase, const char* password_in, char** password_out, const char* heading, int retries, unsigned int auto_close_ms)
+int Interface_GUIDialogKeyboard::show_and_verify_password(KODI_HANDLE kodiBase,
+ const char* password_in,
+ char** password_out,
+ const char* heading,
+ int retries,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!password_in || !password_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (password_in='%p', "
- "password_out='%p', heading='%p') on addon '%s'",
- __FUNCTION__, password_in, static_cast<void*>(password_out), heading,
- addon->ID().c_str());
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (password_in='{}', "
+ "password_out='{}', heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(password_in), static_cast<void*>(password_out),
+ static_cast<const void*>(heading), addon->ID());
return false;
}
@@ -221,21 +259,26 @@ int Interface_GUIDialogKeyboard::show_and_verify_password(void* kodiBase, const
return iRet;
}
-bool Interface_GUIDialogKeyboard::show_and_get_filter(void* kodiBase, const char* text_in, char** text_out, bool searching, unsigned int auto_close_ms)
+bool Interface_GUIDialogKeyboard::show_and_get_filter(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ bool searching,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
if (!text_in || !text_out)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogKeyboard::%s - invalid handler data (text_in='%p', "
- "text_out='%p') on addon '%s'",
- __FUNCTION__, text_in, static_cast<void*>(text_out), addon->ID().c_str());
+ "Interface_GUIDialogKeyboard::{} - invalid handler data (text_in='{}', "
+ "text_out='{}') on addon '{}'",
+ __func__, static_cast<const void*>(text_in), static_cast<void*>(text_out),
+ addon->ID());
return false;
}
@@ -247,29 +290,30 @@ bool Interface_GUIDialogKeyboard::show_and_get_filter(void* kodiBase, const char
return bRet;
}
-bool Interface_GUIDialogKeyboard::send_text_to_active_keyboard(void* kodiBase, const char* text, bool close_keyboard)
+bool Interface_GUIDialogKeyboard::send_text_to_active_keyboard(KODI_HANDLE kodiBase,
+ const char* text,
+ bool close_keyboard)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
return CGUIKeyboardFactory::SendTextToActiveKeyboard(text, close_keyboard);
}
-bool Interface_GUIDialogKeyboard::is_keyboard_activated(void* kodiBase)
+bool Interface_GUIDialogKeyboard::is_keyboard_activated(KODI_HANDLE kodiBase)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogKeyboard::{} - invalid data", __func__);
return false;
}
return CGUIKeyboardFactory::isKeyboardActivated();
}
-} /* extern "C" */
} /* namespace ADDON */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Keyboard.h b/xbmc/addons/interfaces/gui/dialogs/Keyboard.h
index 433c52d3ae..fb7d6b9d59 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Keyboard.h
+++ b/xbmc/addons/interfaces/gui/dialogs/Keyboard.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/keyboard.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,18 +42,53 @@ namespace ADDON
* class.
*/
//@{
- static bool show_and_get_input_with_head(void* kodiBase, const char* text_in, char** text_out, const char* heading, bool allow_empty_result, bool hidden_input, unsigned int auto_close_ms);
- static bool show_and_get_input(void* kodiBase, const char* text_in, char** text_out, bool allow_empty_result, unsigned int auto_close_ms);
- static bool show_and_get_new_password_with_head(void* kodiBase, const char* password_in, char** password_out, const char* heading, bool allow_empty_result, unsigned int auto_close_ms);
- static bool show_and_get_new_password(void* kodiBase, const char* password_in, char** password_out, unsigned int auto_close_ms);
- static bool show_and_verify_new_password_with_head(void* kodiBase, char** password_out, const char* heading, bool allowEmpty, unsigned int auto_close_ms);
- static bool show_and_verify_new_password(void* kodiBase, char** password_out, unsigned int auto_close_ms);
- static int show_and_verify_password(void* kodiBase, const char* password_in, char** password_out, const char* heading, int retries, unsigned int auto_close_ms);
- static bool show_and_get_filter(void* kodiBase, const char* text_in, char** text_out, bool searching, unsigned int auto_close_ms);
- static bool send_text_to_active_keyboard(void* kodiBase, const char* text, bool close_keyboard);
- static bool is_keyboard_activated(void* kodiBase);
+ static 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 hidden_input,
+ unsigned int auto_close_ms);
+ static bool show_and_get_input(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ bool allow_empty_result,
+ unsigned int auto_close_ms);
+ static 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);
+ static bool show_and_get_new_password(KODI_HANDLE kodiBase,
+ const char* password_in,
+ char** password_out,
+ unsigned int auto_close_ms);
+ static bool show_and_verify_new_password_with_head(KODI_HANDLE kodiBase,
+ char** password_out,
+ const char* heading,
+ bool allowEmpty,
+ unsigned int auto_close_ms);
+ static bool show_and_verify_new_password(KODI_HANDLE kodiBase,
+ char** password_out,
+ unsigned int auto_close_ms);
+ static 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);
+ static bool show_and_get_filter(KODI_HANDLE kodiBase,
+ const char* text_in,
+ char** text_out,
+ bool searching,
+ unsigned int auto_close_ms);
+ static bool send_text_to_active_keyboard(KODI_HANDLE kodiBase,
+ const char* text,
+ bool close_keyboard);
+ static bool is_keyboard_activated(KODI_HANDLE kodiBase);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Numeric.cpp b/xbmc/addons/interfaces/gui/dialogs/Numeric.cpp
index 2787b34db2..a78aa4af60 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Numeric.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/Numeric.cpp
@@ -14,36 +14,38 @@
#include "dialogs/GUIDialogNumeric.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIDialogNumeric::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogNumeric = static_cast<AddonToKodiFuncTable_kodi_gui_dialogNumeric*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogNumeric)));
+ addonInterface->toKodi->kodi_gui->dialogNumeric =
+ new AddonToKodiFuncTable_kodi_gui_dialogNumeric();
- addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_verify_new_password = show_and_verify_new_password;
- addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_verify_password = show_and_verify_password;
+ addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_verify_new_password =
+ show_and_verify_new_password;
+ addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_verify_password =
+ show_and_verify_password;
addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_verify_input = show_and_verify_input;
addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_get_time = show_and_get_time;
addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_get_date = show_and_get_date;
- addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_get_ip_address = show_and_get_ip_address;
+ addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_get_ip_address =
+ show_and_get_ip_address;
addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_get_number = show_and_get_number;
addonInterface->toKodi->kodi_gui->dialogNumeric->show_and_get_seconds = show_and_get_seconds;
}
void Interface_GUIDialogNumeric::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogNumeric);
+ delete addonInterface->toKodi->kodi_gui->dialogNumeric;
}
-bool Interface_GUIDialogNumeric::show_and_verify_new_password(void* kodiBase, char** password)
+bool Interface_GUIDialogNumeric::show_and_verify_new_password(KODI_HANDLE kodiBase, char** password)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return false;
}
@@ -54,21 +56,25 @@ bool Interface_GUIDialogNumeric::show_and_verify_new_password(void* kodiBase, ch
return bRet;
}
-int Interface_GUIDialogNumeric::show_and_verify_password(void* kodiBase, const char* password, const char* heading, int retries)
+int Interface_GUIDialogNumeric::show_and_verify_password(KODI_HANDLE kodiBase,
+ const char* password,
+ const char* heading,
+ int retries)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return -1;
}
if (!password || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogNumeric::%s - invalid handler data (password='%p', heading='%p') "
- "on addon '%s'",
- __FUNCTION__, password, heading, addon->ID().c_str());
+ "Interface_GUIDialogNumeric::{} - invalid handler data (password='{}', heading='{}') "
+ "on addon '{}'",
+ __func__, static_cast<const void*>(password), static_cast<const void*>(heading),
+ addon->ID());
return -1;
}
@@ -76,27 +82,32 @@ int Interface_GUIDialogNumeric::show_and_verify_password(void* kodiBase, const c
return CGUIDialogNumeric::ShowAndVerifyPassword(pw, heading, retries);
}
-bool Interface_GUIDialogNumeric::show_and_verify_input(void* kodiBase, const char* verify_in, char** verify_out, const char* heading, bool verify_input)
+bool Interface_GUIDialogNumeric::show_and_verify_input(KODI_HANDLE kodiBase,
+ const char* verify_in,
+ char** verify_out,
+ const char* heading,
+ bool verify_input)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return false;
}
if (!verify_in || !verify_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogNumeric::%s - invalid handler data (verify_in='%p', "
- "verify_out='%p', heading='%p') on addon '%s'",
- __FUNCTION__, verify_in, static_cast<void*>(verify_out), heading,
- addon->ID().c_str());
+ "Interface_GUIDialogNumeric::{} - invalid handler data (verify_in='{}', "
+ "verify_out='{}', heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(verify_in), static_cast<void*>(verify_out),
+ static_cast<const void*>(heading), addon->ID());
return false;
}
std::string str = verify_in;
- if (CGUIDialogNumeric::ShowAndVerifyInput(str, heading, verify_input) == InputVerificationResult::SUCCESS)
+ if (CGUIDialogNumeric::ShowAndVerifyInput(str, heading, verify_input) ==
+ InputVerificationResult::SUCCESS)
{
*verify_out = strdup(str.c_str());
return true;
@@ -104,21 +115,23 @@ bool Interface_GUIDialogNumeric::show_and_verify_input(void* kodiBase, const cha
return false;
}
-bool Interface_GUIDialogNumeric::show_and_get_time(void* kodiBase, tm* time, const char* heading)
+bool Interface_GUIDialogNumeric::show_and_get_time(KODI_HANDLE kodiBase,
+ tm* time,
+ const char* heading)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return false;
}
if (!time || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogNumeric::%s - invalid handler data (time='%p', heading='%p') on "
- "addon '%s'",
- __FUNCTION__, static_cast<void*>(time), heading, addon->ID().c_str());
+ "Interface_GUIDialogNumeric::{} - invalid handler data (time='{}', heading='{}') on "
+ "addon '{}'",
+ __func__, static_cast<void*>(time), static_cast<const void*>(heading), addon->ID());
return false;
}
@@ -134,21 +147,23 @@ bool Interface_GUIDialogNumeric::show_and_get_time(void* kodiBase, tm* time, con
return false;
}
-bool Interface_GUIDialogNumeric::show_and_get_date(void* kodiBase, tm *date, const char *heading)
+bool Interface_GUIDialogNumeric::show_and_get_date(KODI_HANDLE kodiBase,
+ tm* date,
+ const char* heading)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return false;
}
if (!date || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogNumeric::%s - invalid handler data (date='%p', heading='%p') on "
- "addon '%s'",
- __FUNCTION__, static_cast<void*>(date), heading, addon->ID().c_str());
+ "Interface_GUIDialogNumeric::{} - invalid handler data (date='{}', heading='{}') on "
+ "addon '{}'",
+ __func__, static_cast<void*>(date), static_cast<const void*>(heading), addon->ID());
return false;
}
@@ -164,22 +179,25 @@ bool Interface_GUIDialogNumeric::show_and_get_date(void* kodiBase, tm *date, con
return false;
}
-bool Interface_GUIDialogNumeric::show_and_get_ip_address(void* kodiBase, const char* ip_address_in, char** ip_address_out, const char *heading)
+bool Interface_GUIDialogNumeric::show_and_get_ip_address(KODI_HANDLE kodiBase,
+ const char* ip_address_in,
+ char** ip_address_out,
+ const char* heading)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return false;
}
if (!ip_address_in || !ip_address_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogNumeric::%s - invalid handler data (ip_address_in='%p', "
- "ip_address_out='%p', heading='%p') on addon '%s'",
- __FUNCTION__, ip_address_in, static_cast<void*>(ip_address_out), heading,
- addon->ID().c_str());
+ "Interface_GUIDialogNumeric::{} - invalid handler data (ip_address_in='{}', "
+ "ip_address_out='{}', heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(ip_address_in), static_cast<void*>(ip_address_out),
+ static_cast<const void*>(heading), addon->ID());
return false;
}
@@ -190,22 +208,26 @@ bool Interface_GUIDialogNumeric::show_and_get_ip_address(void* kodiBase, const c
return bRet;
}
-bool Interface_GUIDialogNumeric::show_and_get_number(void* kodiBase, const char* number_in, char** number_out, const char *heading, unsigned int auto_close_ms)
+bool Interface_GUIDialogNumeric::show_and_get_number(KODI_HANDLE kodiBase,
+ const char* number_in,
+ char** number_out,
+ const char* heading,
+ unsigned int auto_close_ms)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return false;
}
if (!number_in || !number_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogNumeric::%s - invalid handler data (number_in='%p', "
- "number_out='%p', heading='%p') on addon '%s'",
- __FUNCTION__, number_in, static_cast<void*>(number_out), heading,
- addon->ID().c_str());
+ "Interface_GUIDialogNumeric::{} - invalid handler data (number_in='{}', "
+ "number_out='{}', heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(number_in), static_cast<void*>(number_out),
+ static_cast<const void*>(heading), addon->ID());
return false;
}
@@ -216,21 +238,25 @@ bool Interface_GUIDialogNumeric::show_and_get_number(void* kodiBase, const char*
return bRet;
}
-bool Interface_GUIDialogNumeric::show_and_get_seconds(void* kodiBase, const char* time_in, char** time_out, const char *heading)
+bool Interface_GUIDialogNumeric::show_and_get_seconds(KODI_HANDLE kodiBase,
+ const char* time_in,
+ char** time_out,
+ const char* heading)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogNumeric::{} - invalid data", __func__);
return false;
}
if (!time_in || !time_out || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogNumeric::%s - invalid handler data (time_in='%p', time_out='%p', "
- "heading='%p') on addon '%s'",
- __FUNCTION__, time_in, static_cast<void*>(time_out), heading, addon->ID().c_str());
+ "Interface_GUIDialogNumeric::{} - invalid handler data (time_in='{}', time_out='{}', "
+ "heading='{}') on addon '{}'",
+ __func__, static_cast<const void*>(time_in), static_cast<void*>(time_out),
+ static_cast<const void*>(heading), addon->ID());
return false;
}
@@ -242,4 +268,3 @@ bool Interface_GUIDialogNumeric::show_and_get_seconds(void* kodiBase, const char
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Numeric.h b/xbmc/addons/interfaces/gui/dialogs/Numeric.h
index 0d2f852f0d..a54ad525b5 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Numeric.h
+++ b/xbmc/addons/interfaces/gui/dialogs/Numeric.h
@@ -8,15 +8,15 @@
#pragma once
-#include <time.h>
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/numeric.h"
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -42,16 +42,33 @@ namespace ADDON
* class.
*/
//@{
- static bool show_and_verify_new_password(void* kodiBase, char** password);
- static int show_and_verify_password(void* kodiBase, const char* password, const char *heading, int retries);
- static bool show_and_verify_input(void* kodiBase, const char* verify_in, char** verify_out, const char* heading, bool verify_input);
- static bool show_and_get_time(void* kodiBase, tm *time, const char *heading);
- static bool show_and_get_date(void* kodiBase, tm *date, const char *heading);
- static bool show_and_get_ip_address(void* kodiBase, const char* ip_address_in, char** ip_address_out, const char *heading);
- static bool show_and_get_number(void* kodiBase, const char* number_in, char** number_out, const char *heading, unsigned int auto_close_ms);
- static bool show_and_get_seconds(void* kodiBase, const char* time_in, char** time_out, const char *heading);
+ static bool show_and_verify_new_password(KODI_HANDLE kodiBase, char** password);
+ static int show_and_verify_password(KODI_HANDLE kodiBase,
+ const char* password,
+ const char* heading,
+ int retries);
+ static bool show_and_verify_input(KODI_HANDLE kodiBase,
+ const char* verify_in,
+ char** verify_out,
+ const char* heading,
+ bool verify_input);
+ static bool show_and_get_time(KODI_HANDLE kodiBase, tm* time, const char* heading);
+ static bool show_and_get_date(KODI_HANDLE kodiBase, tm* date, const char* heading);
+ static bool show_and_get_ip_address(KODI_HANDLE kodiBase,
+ const char* ip_address_in,
+ char** ip_address_out,
+ const char* heading);
+ static bool show_and_get_number(KODI_HANDLE kodiBase,
+ const char* number_in,
+ char** number_out,
+ const char* heading,
+ unsigned int auto_close_ms);
+ static bool show_and_get_seconds(KODI_HANDLE kodiBase,
+ const char* time_in,
+ char** time_out,
+ const char* heading);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/OK.cpp b/xbmc/addons/interfaces/gui/dialogs/OK.cpp
index c2ca542dd4..90e9d6999b 100644
--- a/xbmc/addons/interfaces/gui/dialogs/OK.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/OK.cpp
@@ -16,51 +16,58 @@
using namespace KODI::MESSAGING;
-extern "C"
-{
namespace ADDON
{
void Interface_GUIDialogOK::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogOK = static_cast<AddonToKodiFuncTable_kodi_gui_dialogOK*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogOK)));
+ addonInterface->toKodi->kodi_gui->dialogOK = new AddonToKodiFuncTable_kodi_gui_dialogOK();
- addonInterface->toKodi->kodi_gui->dialogOK->show_and_get_input_single_text = show_and_get_input_single_text;
- addonInterface->toKodi->kodi_gui->dialogOK->show_and_get_input_line_text = show_and_get_input_line_text;
+ addonInterface->toKodi->kodi_gui->dialogOK->show_and_get_input_single_text =
+ show_and_get_input_single_text;
+ addonInterface->toKodi->kodi_gui->dialogOK->show_and_get_input_line_text =
+ show_and_get_input_line_text;
}
void Interface_GUIDialogOK::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogOK);
+ delete addonInterface->toKodi->kodi_gui->dialogOK;
}
-void Interface_GUIDialogOK::show_and_get_input_single_text(void* kodiBase, const char *heading, const char *text)
+void Interface_GUIDialogOK::show_and_get_input_single_text(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon || !heading || !text)
{
- CLog::Log(LOGERROR,
- "Interface_GUIDialogOK:%s - invalid data (addon='%p', heading='%p', text='%p')",
- __FUNCTION__, kodiBase, heading, text);
+ CLog::Log(
+ LOGERROR, "Interface_GUIDialogOK:{} - invalid data (addon='{}', heading='{}', text='{}')",
+ __func__, kodiBase, static_cast<const void*>(heading), static_cast<const void*>(text));
return;
}
HELPERS::ShowOKDialogText(CVariant{heading}, CVariant{text});
}
-void Interface_GUIDialogOK::show_and_get_input_line_text(void* kodiBase, const char *heading, const char *line0, const char *line1, const char *line2)
+void Interface_GUIDialogOK::show_and_get_input_line_text(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* line0,
+ const char* line1,
+ const char* line2)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon || !heading || !line0 || !line1 || !line2)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogOK::%s - invalid data (addon='%p', heading='%p', line0='%p', "
- "line1='%p', line2='%p')",
- __FUNCTION__, kodiBase, heading, line0, line1, line2);
+ "Interface_GUIDialogOK::{} - invalid data (addon='{}', heading='{}', line0='{}', "
+ "line1='{}', line2='{}')",
+ __func__, kodiBase, static_cast<const void*>(heading),
+ static_cast<const void*>(line0), static_cast<const void*>(line1),
+ static_cast<const void*>(line2));
return;
}
- HELPERS::ShowOKDialogLines(CVariant{ heading }, CVariant{ line0 }, CVariant{ line1 }, CVariant{ line2 });
+ HELPERS::ShowOKDialogLines(CVariant{heading}, CVariant{line0}, CVariant{line1}, CVariant{line2});
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/OK.h b/xbmc/addons/interfaces/gui/dialogs/OK.h
index 41f1615467..fd13719a99 100644
--- a/xbmc/addons/interfaces/gui/dialogs/OK.h
+++ b/xbmc/addons/interfaces/gui/dialogs/OK.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/ok.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,10 +42,16 @@ namespace ADDON
* class.
*/
//@{
- static void show_and_get_input_single_text(void* kodiBase, const char *heading, const char *text);
- static void show_and_get_input_line_text(void* kodiBase, const char *heading, const char *line0, const char *line1, const char *line2);
+ static void show_and_get_input_single_text(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* text);
+ static void show_and_get_input_line_text(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* line0,
+ const char* line1,
+ const char* line2);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Progress.cpp b/xbmc/addons/interfaces/gui/dialogs/Progress.cpp
index fdb79d5ab5..ff6c7424ba 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Progress.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/Progress.cpp
@@ -19,12 +19,11 @@
namespace ADDON
{
-extern "C"
-{
void Interface_GUIDialogProgress::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogProgress = static_cast<AddonToKodiFuncTable_kodi_gui_dialogProgress*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogProgress)));
+ addonInterface->toKodi->kodi_gui->dialogProgress =
+ new AddonToKodiFuncTable_kodi_gui_dialogProgress();
addonInterface->toKodi->kodi_gui->dialogProgress->new_dialog = new_dialog;
addonInterface->toKodi->kodi_gui->dialogProgress->delete_dialog = delete_dialog;
@@ -43,271 +42,287 @@ void Interface_GUIDialogProgress::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIDialogProgress::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogProgress);
+ delete addonInterface->toKodi->kodi_gui->dialogProgress;
}
-void* Interface_GUIDialogProgress::new_dialog(void* kodiBase)
+KODI_GUI_HANDLE Interface_GUIDialogProgress::new_dialog(KODI_HANDLE kodiBase)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return nullptr;
}
- CGUIDialogProgress *dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogProgress>(WINDOW_DIALOG_PROGRESS);
+ CGUIDialogProgress* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogProgress>(
+ WINDOW_DIALOG_PROGRESS);
if (!dialog)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (dialog='%p') on addon '%s'",
- __FUNCTION__, static_cast<void*>(dialog), addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (dialog='{}') on addon '{}'",
+ __func__, static_cast<void*>(dialog), addon->ID());
return nullptr;
}
return dialog;
}
-void Interface_GUIDialogProgress::delete_dialog(void* kodiBase, void* handle)
+void Interface_GUIDialogProgress::delete_dialog(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->Close();
}
-void Interface_GUIDialogProgress::open(void* kodiBase, void* handle)
+void Interface_GUIDialogProgress::open(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->Open();
}
-void Interface_GUIDialogProgress::set_heading(void* kodiBase, void* handle, const char* heading)
+void Interface_GUIDialogProgress::set_heading(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ const char* heading)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle || !heading)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p', heading='%p') "
- "on addon '%s'",
- __FUNCTION__, handle, static_cast<const void*>(heading), addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}', heading='{}') "
+ "on addon '{}'",
+ __func__, handle, static_cast<const void*>(heading), addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->SetHeading(heading);
}
-void Interface_GUIDialogProgress::set_line(void* kodiBase, void* handle, unsigned int line, const char* text)
+void Interface_GUIDialogProgress::set_line(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ unsigned int line,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle || !text)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p', text='%p') on "
- "addon '%s'",
- __FUNCTION__, handle, static_cast<const void*>(text), addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}', text='{}') on "
+ "addon '{}'",
+ __func__, handle, static_cast<const void*>(text), addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->SetLine(line, text);
}
-void Interface_GUIDialogProgress::set_can_cancel(void* kodiBase, void* handle, bool canCancel)
+void Interface_GUIDialogProgress::set_can_cancel(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ bool canCancel)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->SetCanCancel(canCancel);
}
-bool Interface_GUIDialogProgress::is_canceled(void* kodiBase, void* handle)
+bool Interface_GUIDialogProgress::is_canceled(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return false;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return false;
}
return static_cast<CGUIDialogProgress*>(handle)->IsCanceled();
}
-void Interface_GUIDialogProgress::set_percentage(void* kodiBase, void* handle, int percentage)
+void Interface_GUIDialogProgress::set_percentage(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ int percentage)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->SetPercentage(percentage);
}
-int Interface_GUIDialogProgress::get_percentage(void* kodiBase, void* handle)
+int Interface_GUIDialogProgress::get_percentage(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return 0;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return 0;
}
return static_cast<CGUIDialogProgress*>(handle)->GetPercentage();
}
-void Interface_GUIDialogProgress::show_progress_bar(void* kodiBase, void* handle, bool onOff)
+void Interface_GUIDialogProgress::show_progress_bar(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ bool onOff)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->ShowProgressBar(onOff);
}
-void Interface_GUIDialogProgress::set_progress_max(void* kodiBase, void* handle, int max)
+void Interface_GUIDialogProgress::set_progress_max(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ int max)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->SetProgressMax(max);
}
-void Interface_GUIDialogProgress::set_progress_advance(void* kodiBase, void* handle, int nSteps)
+void Interface_GUIDialogProgress::set_progress_advance(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ int nSteps)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return;
}
static_cast<CGUIDialogProgress*>(handle)->SetProgressAdvance(nSteps);
}
-bool Interface_GUIDialogProgress::abort(void* kodiBase, void* handle)
+bool Interface_GUIDialogProgress::abort(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogProgress::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogProgress::{} - invalid data", __func__);
return false;
}
if (!handle)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogProgress::%s - invalid handler data (handle='%p') on addon '%s'",
- __FUNCTION__, handle, addon->ID().c_str());
+ "Interface_GUIDialogProgress::{} - invalid handler data (handle='{}') on addon '{}'",
+ __func__, handle, addon->ID());
return false;
}
return static_cast<CGUIDialogProgress*>(handle)->Abort();
}
-} /* extern "C" */
} /* namespace ADDON */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Progress.h b/xbmc/addons/interfaces/gui/dialogs/Progress.h
index c3f4b34c95..ba31f3c74c 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Progress.h
+++ b/xbmc/addons/interfaces/gui/dialogs/Progress.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/progress.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,21 +42,24 @@ namespace ADDON
* class.
*/
//@{
- static void* new_dialog(void* kodiBase);
- static void delete_dialog(void* kodiBase, void* handle);
- static void open(void* kodiBase, void* handle);
- static void set_heading(void* kodiBase, void* handle, const char* heading);
- static void set_line(void* kodiBase, void* handle, unsigned int line, const char* text);
- static void set_can_cancel(void* kodiBase, void* handle, bool canCancel);
- static bool is_canceled(void* kodiBase, void* handle);
- static void set_percentage(void* kodiBase, void* handle, int percentage);
- static int get_percentage(void* kodiBase, void* handle);
- static void show_progress_bar(void* kodiBase, void* handle, bool bOnOff);
- static void set_progress_max(void* kodiBase, void* handle, int max);
- static void set_progress_advance(void* kodiBase, void* handle, int nSteps);
- static bool abort(void* kodiBase, void* handle);
+ static KODI_GUI_HANDLE new_dialog(KODI_HANDLE kodiBase);
+ static void delete_dialog(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void open(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void set_heading(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, const char* heading);
+ static void set_line(KODI_HANDLE kodiBase,
+ KODI_GUI_HANDLE handle,
+ unsigned int line,
+ const char* text);
+ static void set_can_cancel(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, bool canCancel);
+ static bool is_canceled(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void set_percentage(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, int percentage);
+ static int get_percentage(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
+ static void show_progress_bar(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, bool bOnOff);
+ static void set_progress_max(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, int max);
+ static void set_progress_advance(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle, int nSteps);
+ static bool abort(KODI_HANDLE kodiBase, KODI_GUI_HANDLE handle);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Select.cpp b/xbmc/addons/interfaces/gui/dialogs/Select.cpp
index a688587c89..7ad6ed667f 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Select.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/Select.cpp
@@ -19,12 +19,10 @@
namespace ADDON
{
-extern "C"
-{
void Interface_GUIDialogSelect::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogSelect = static_cast<AddonToKodiFuncTable_kodi_gui_dialogSelect*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogSelect)));
+ addonInterface->toKodi->kodi_gui->dialogSelect = new AddonToKodiFuncTable_kodi_gui_dialogSelect();
addonInterface->toKodi->kodi_gui->dialogSelect->open = open;
addonInterface->toKodi->kodi_gui->dialogSelect->open_multi_select = open_multi_select;
@@ -32,26 +30,33 @@ void Interface_GUIDialogSelect::Init(AddonGlobalInterface* addonInterface)
void Interface_GUIDialogSelect::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogSelect);
+ delete addonInterface->toKodi->kodi_gui->dialogSelect;
}
-int Interface_GUIDialogSelect::open(void* kodiBase, const char *heading, const char *entries[], unsigned int size, int selected, unsigned int autoclose)
+int Interface_GUIDialogSelect::open(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entries[],
+ unsigned int size,
+ int selected,
+ unsigned int autoclose)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogSelect::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogSelect::{} - invalid data", __func__);
return -1;
}
- CGUIDialogSelect* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
+ CGUIDialogSelect* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(
+ WINDOW_DIALOG_SELECT);
if (!heading || !entries || !dialog)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogSelect::%s - invalid handler data (heading='%p', entries='%p', "
- "dialog='%p') on addon '%s'",
- __FUNCTION__, heading, static_cast<const void*>(entries), static_cast<void*>(dialog),
- addon->ID().c_str());
+ "Interface_GUIDialogSelect::{} - invalid handler data (heading='{}', entries='{}', "
+ "dialog='{}') on addon '{}'",
+ __func__, static_cast<const void*>(heading), static_cast<const void*>(entries),
+ static_cast<void*>(dialog), addon->ID());
return -1;
}
@@ -71,25 +76,32 @@ int Interface_GUIDialogSelect::open(void* kodiBase, const char *heading, const c
}
-bool Interface_GUIDialogSelect::open_multi_select(void* kodiBase, const char *heading, const char *entryIDs[], const char *entryNames[],
- bool entriesSelected[], unsigned int size, unsigned int autoclose)
+bool Interface_GUIDialogSelect::open_multi_select(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entryIDs[],
+ const char* entryNames[],
+ bool entriesSelected[],
+ unsigned int size,
+ unsigned int autoclose)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogMultiSelect::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogMultiSelect::{} - invalid data", __func__);
return false;
}
- CGUIDialogSelect* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
+ CGUIDialogSelect* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(
+ WINDOW_DIALOG_SELECT);
if (!heading || !entryIDs || !entryNames || !entriesSelected || !dialog)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogMultiSelect::%s - invalid handler data (heading='%p', "
- "entryIDs='%p', entryNames='%p', entriesSelected='%p', dialog='%p') on addon '%s'",
- __FUNCTION__, heading, static_cast<const void*>(entryIDs),
+ "Interface_GUIDialogMultiSelect::{} - invalid handler data (heading='{}', "
+ "entryIDs='{}', entryNames='{}', entriesSelected='{}', dialog='{}') on addon '{}'",
+ __func__, static_cast<const void*>(heading), static_cast<const void*>(entryIDs),
static_cast<const void*>(entryNames), static_cast<void*>(entriesSelected),
- static_cast<void*>(dialog), addon->ID().c_str());
+ static_cast<void*>(dialog), addon->ID());
return false;
}
@@ -128,5 +140,4 @@ bool Interface_GUIDialogSelect::open_multi_select(void* kodiBase, const char *he
return true;
}
-} /* extern "C" */
} /* namespace ADDON */
diff --git a/xbmc/addons/interfaces/gui/dialogs/Select.h b/xbmc/addons/interfaces/gui/dialogs/Select.h
index cca072da03..5f2d0ef6aa 100644
--- a/xbmc/addons/interfaces/gui/dialogs/Select.h
+++ b/xbmc/addons/interfaces/gui/dialogs/Select.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/select.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,11 +42,21 @@ namespace ADDON
* class.
*/
//@{
- static int open(void* kodiBase, const char *heading, const char *entries[], unsigned int size, int selected, unsigned int autoclose);
- static bool open_multi_select(void* kodiBase, const char *heading, const char *entryIDs[], const char *entryNames[],
- bool entriesSelected[], unsigned int size, unsigned int autoclose);
+ static int open(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entries[],
+ unsigned int size,
+ int selected,
+ unsigned int autoclose);
+ static bool open_multi_select(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* entryIDs[],
+ const char* entryNames[],
+ bool entriesSelected[],
+ unsigned int size,
+ unsigned int autoclose);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/TextViewer.cpp b/xbmc/addons/interfaces/gui/dialogs/TextViewer.cpp
index b558eb9ff5..637975a73b 100644
--- a/xbmc/addons/interfaces/gui/dialogs/TextViewer.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/TextViewer.cpp
@@ -16,39 +16,43 @@
#include "guilib/GUIWindowManager.h"
#include "utils/log.h"
-extern "C"
-{
namespace ADDON
{
void Interface_GUIDialogTextViewer::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogTextViewer = static_cast<AddonToKodiFuncTable_kodi_gui_dialogTextViewer*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogTextViewer)));
+ addonInterface->toKodi->kodi_gui->dialogTextViewer =
+ new AddonToKodiFuncTable_kodi_gui_dialogTextViewer();
addonInterface->toKodi->kodi_gui->dialogTextViewer->open = open;
}
void Interface_GUIDialogTextViewer::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogTextViewer);
+ delete addonInterface->toKodi->kodi_gui->dialogTextViewer;
}
-void Interface_GUIDialogTextViewer::open(void* kodiBase, const char *heading, const char *text)
+void Interface_GUIDialogTextViewer::open(KODI_HANDLE kodiBase,
+ const char* heading,
+ const char* text)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogTextViewer::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogTextViewer::{} - invalid data", __func__);
return;
}
- CGUIDialogTextViewer* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogTextViewer>(WINDOW_DIALOG_TEXT_VIEWER);
+ CGUIDialogTextViewer* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogTextViewer>(
+ WINDOW_DIALOG_TEXT_VIEWER);
if (!heading || !text || !dialog)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogTextViewer::%s - invalid handler data (heading='%p', text='%p', "
- "dialog='%p') on addon '%s'",
- __FUNCTION__, heading, text, static_cast<void*>(dialog), addon->ID().c_str());
+ "Interface_GUIDialogTextViewer::{} - invalid handler data (heading='{}', text='{}', "
+ "dialog='{}') on addon '{}'",
+ __func__, static_cast<const void*>(heading), static_cast<const void*>(text),
+ static_cast<void*>(dialog), addon->ID());
return;
}
@@ -58,4 +62,3 @@ void Interface_GUIDialogTextViewer::open(void* kodiBase, const char *heading, co
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/TextViewer.h b/xbmc/addons/interfaces/gui/dialogs/TextViewer.h
index e86356a439..873dbbba4e 100644
--- a/xbmc/addons/interfaces/gui/dialogs/TextViewer.h
+++ b/xbmc/addons/interfaces/gui/dialogs/TextViewer.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/text_viewer.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,9 +42,9 @@ namespace ADDON
* class.
*/
//@{
- static void open(void* kodiBase, const char *heading, const char *text);
+ static void open(KODI_HANDLE kodiBase, const char* heading, const char* text);
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp b/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp
index fb84c46d1c..2c635fb1f9 100644
--- a/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp
@@ -17,26 +17,27 @@
using namespace KODI::MESSAGING;
using KODI::MESSAGING::HELPERS::DialogResponse;
-extern "C"
-{
namespace ADDON
{
void Interface_GUIDialogYesNo::Init(AddonGlobalInterface* addonInterface)
{
- addonInterface->toKodi->kodi_gui->dialogYesNo = static_cast<AddonToKodiFuncTable_kodi_gui_dialogYesNo*>(malloc(sizeof(AddonToKodiFuncTable_kodi_gui_dialogYesNo)));
-
- addonInterface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_single_text = show_and_get_input_single_text;
- addonInterface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_text = show_and_get_input_line_text;
- addonInterface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_button_text = show_and_get_input_line_button_text;
+ addonInterface->toKodi->kodi_gui->dialogYesNo = new AddonToKodiFuncTable_kodi_gui_dialogYesNo();
+
+ addonInterface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_single_text =
+ show_and_get_input_single_text;
+ addonInterface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_text =
+ show_and_get_input_line_text;
+ addonInterface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_button_text =
+ show_and_get_input_line_button_text;
}
void Interface_GUIDialogYesNo::DeInit(AddonGlobalInterface* addonInterface)
{
- free(addonInterface->toKodi->kodi_gui->dialogYesNo);
+ delete addonInterface->toKodi->kodi_gui->dialogYesNo;
}
-bool Interface_GUIDialogYesNo::show_and_get_input_single_text(void* kodiBase,
+bool Interface_GUIDialogYesNo::show_and_get_input_single_text(KODI_HANDLE kodiBase,
const char* heading,
const char* text,
bool* canceled,
@@ -46,17 +47,18 @@ bool Interface_GUIDialogYesNo::show_and_get_input_single_text(void* kodiBase,
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogYesNo::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogYesNo::{} - invalid data", __func__);
return false;
}
if (!heading || !text || !canceled || !noLabel || !yesLabel)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogYesNo::%s - invalid handler data (heading='%p', text='%p', "
- "canceled='%p', noLabel='%p', yesLabel='%p') on addon '%s'",
- __FUNCTION__, heading, text, static_cast<void*>(canceled), noLabel, yesLabel,
- addon->ID().c_str());
+ "Interface_GUIDialogYesNo::{} - invalid handler data (heading='{}', text='{}', "
+ "canceled='{}', noLabel='{}', yesLabel='{}') on addon '{}'",
+ __func__, static_cast<const void*>(heading), static_cast<const void*>(text),
+ static_cast<void*>(canceled), static_cast<const void*>(noLabel),
+ static_cast<const void*>(yesLabel), addon->ID());
return false;
}
@@ -65,7 +67,7 @@ bool Interface_GUIDialogYesNo::show_and_get_input_single_text(void* kodiBase,
return (result == DialogResponse::YES);
}
-bool Interface_GUIDialogYesNo::show_and_get_input_line_text(void* kodiBase,
+bool Interface_GUIDialogYesNo::show_and_get_input_line_text(KODI_HANDLE kodiBase,
const char* heading,
const char* line0,
const char* line1,
@@ -76,25 +78,27 @@ bool Interface_GUIDialogYesNo::show_and_get_input_line_text(void* kodiBase,
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogYesNo::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogYesNo::{} - invalid data", __func__);
return false;
}
if (!heading || !line0 || !line1 || !line2 || !noLabel || !yesLabel)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogYesNo::%s - invalid handler data (heading='%p', line0='%p', "
- "line1='%p', line2='%p', "
- "noLabel='%p', yesLabel='%p') on addon '%s'",
- __FUNCTION__, heading, line0, line1, line2, noLabel, yesLabel, addon->ID().c_str());
+ "Interface_GUIDialogYesNo::{} - invalid handler data (heading='{}', line0='{}', "
+ "line1='{}', line2='{}', "
+ "noLabel='{}', yesLabel='{}') on addon '{}'",
+ __func__, static_cast<const void*>(heading), static_cast<const void*>(line0),
+ static_cast<const void*>(line1), static_cast<const void*>(line2),
+ static_cast<const void*>(noLabel), static_cast<const void*>(yesLabel), addon->ID());
return false;
}
return HELPERS::ShowYesNoDialogLines(heading, line0, line1, line2, noLabel, yesLabel) ==
- DialogResponse::YES;
+ DialogResponse::YES;
}
-bool Interface_GUIDialogYesNo::show_and_get_input_line_button_text(void* kodiBase,
+bool Interface_GUIDialogYesNo::show_and_get_input_line_button_text(KODI_HANDLE kodiBase,
const char* heading,
const char* line0,
const char* line1,
@@ -106,25 +110,27 @@ bool Interface_GUIDialogYesNo::show_and_get_input_line_button_text(void* kodiBas
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (!addon)
{
- CLog::Log(LOGERROR, "Interface_GUIDialogYesNo::%s - invalid data", __FUNCTION__);
+ CLog::Log(LOGERROR, "Interface_GUIDialogYesNo::{} - invalid data", __func__);
return false;
}
if (!heading || !line0 || !line1 || !line2 || !canceled || !noLabel || !yesLabel)
{
CLog::Log(LOGERROR,
- "Interface_GUIDialogYesNo::%s - invalid handler data (heading='%p', line0='%p', "
- "line1='%p', line2='%p', "
- "canceled='%p', noLabel='%p', yesLabel='%p') on addon '%s'",
- __FUNCTION__, heading, line0, line1, line2, static_cast<const void*>(canceled),
- noLabel, yesLabel, addon->ID().c_str());
+ "Interface_GUIDialogYesNo::{} - invalid handler data (heading='{}', line0='{}', "
+ "line1='{}', line2='{}', "
+ "canceled='{}', noLabel='{}', yesLabel='{}') on addon '{}'",
+ __func__, static_cast<const void*>(heading), static_cast<const void*>(line0),
+ static_cast<const void*>(line1), static_cast<const void*>(line2),
+ static_cast<const void*>(canceled), static_cast<const void*>(noLabel),
+ static_cast<const void*>(yesLabel), addon->ID());
return false;
}
- DialogResponse result = HELPERS::ShowYesNoDialogLines(heading, line0, line1, line2, noLabel, yesLabel);
+ DialogResponse result =
+ HELPERS::ShowYesNoDialogLines(heading, line0, line1, line2, noLabel, yesLabel);
*canceled = (result == DialogResponse::CANCELLED);
return (result == DialogResponse::YES);
}
} /* namespace ADDON */
-} /* extern "C" */
diff --git a/xbmc/addons/interfaces/gui/dialogs/YesNo.h b/xbmc/addons/interfaces/gui/dialogs/YesNo.h
index b842abf3fa..84e5d73bb7 100644
--- a/xbmc/addons/interfaces/gui/dialogs/YesNo.h
+++ b/xbmc/addons/interfaces/gui/dialogs/YesNo.h
@@ -8,13 +8,15 @@
#pragma once
+#include "addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/yes_no.h"
+
extern "C"
{
-struct AddonGlobalInterface;
+ struct AddonGlobalInterface;
-namespace ADDON
-{
+ namespace ADDON
+ {
/*!
* @brief Global gui Add-on to Kodi callback functions
@@ -40,14 +42,14 @@ namespace ADDON
* class.
*/
//@{
- static bool show_and_get_input_single_text(void* kodiBase,
+ static bool show_and_get_input_single_text(KODI_HANDLE kodiBase,
const char* heading,
const char* text,
bool* canceled,
const char* noLabel,
const char* yesLabel);
- static bool show_and_get_input_line_text(void* kodiBase,
+ static bool show_and_get_input_line_text(KODI_HANDLE kodiBase,
const char* heading,
const char* line0,
const char* line1,
@@ -55,7 +57,7 @@ namespace ADDON
const char* noLabel,
const char* yesLabel);
- static bool show_and_get_input_line_button_text(void* kodiBase,
+ static bool show_and_get_input_line_button_text(KODI_HANDLE kodiBase,
const char* heading,
const char* line0,
const char* line1,
@@ -66,5 +68,5 @@ namespace ADDON
//@}
};
-} /* namespace ADDON */
+ } /* namespace ADDON */
} /* extern "C" */
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Doxyfile b/xbmc/addons/kodi-dev-kit/doxygen/Doxyfile
index 3804747a4a..339249e5d6 100644
--- a/xbmc/addons/kodi-dev-kit/doxygen/Doxyfile
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Doxyfile
@@ -825,6 +825,8 @@ INPUT = main.txt \
../../../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 \
@@ -2489,7 +2491,7 @@ DIRECTORY_GRAPH = YES
# The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES.
-DOT_IMAGE_FORMAT = png
+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.
@@ -2501,7 +2503,7 @@ DOT_IMAGE_FORMAT = png
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
-INTERACTIVE_SVG = NO
+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.
diff --git a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox
index 05080f5d69..acc670ed31 100644
--- a/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox
+++ b/xbmc/addons/kodi-dev-kit/doxygen/Modules/modules_cpp.dox
@@ -142,7 +142,18 @@ Here is a table of the types currently possible:
/*!
\defgroup cpp_kodi_gui Interface - kodi::gui
\ingroup cpp
-\brief **Graphical functions for Windows and Dialogs to show**
+\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
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 0000000000..4950766aef
--- /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 0000000000..dfc2b0aed7
--- /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 0000000000..655b4428dd
--- /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 0000000000..44a1de26eb
--- /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 0000000000..43849f046d
--- /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 0000000000..5a1d8bfa6b
--- /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 0000000000..96a6474c97
--- /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 0000000000..e5398286f8
--- /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 0000000000..b21caf3165
--- /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 0000000000..cc9a0ddf45
--- /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 0000000000..f48a12b516
--- /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 0000000000..9393398b91
--- /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 0000000000..ef50096ee5
--- /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 0000000000..482e361d07
--- /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/include/kodi/AddonBase.h b/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
index f0473679a2..c1a1ba7a14 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
@@ -422,13 +422,13 @@ public:
/// {
/// if (instanceType == ADDON_INSTANCE_SCREENSAVER)
/// {
- /// kodi::Log(ADDON_LOG_NOTICE, "Creating my Screensaver");
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my Screensaver");
/// addonInstance = new CMyScreensaver(instance);
/// return ADDON_STATUS_OK;
/// }
/// else if (instanceType == ADDON_INSTANCE_VISUALIZATION)
/// {
- /// kodi::Log(ADDON_LOG_NOTICE, "Creating my Visualization");
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my Visualization");
/// addonInstance = new CMyVisualization(instance);
/// return ADDON_STATUS_OK;
/// }
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h b/xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h
index 2054ce6720..1cf05fe295 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/Filesystem.h
@@ -110,12 +110,18 @@ public:
/// | 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
@@ -128,6 +134,12 @@ public:
/// @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; }
@@ -167,6 +179,35 @@ public:
/// @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; }
//@}
};
//@}
@@ -777,6 +818,7 @@ inline bool ATTRIBUTE_HIDDEN DirectoryExists(const std::string& path)
/// 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
@@ -793,12 +835,16 @@ inline bool ATTRIBUTE_HIDDEN DirectoryExists(const std::string& path)
/// ...
/// ~~~~~~~~~~~~~
///
-inline bool ATTRIBUTE_HIDDEN RemoveDirectory(const std::string& path)
+inline bool ATTRIBUTE_HIDDEN RemoveDirectory(const std::string& path, bool recursive = false)
{
using namespace kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_filesystem->remove_directory(
- CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
+ if (!recursive)
+ return CAddonBase::m_interface->toKodi->kodi_filesystem->remove_directory(
+ CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
+ else
+ return CAddonBase::m_interface->toKodi->kodi_filesystem->remove_directory_recursive(
+ CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
}
//------------------------------------------------------------------------------
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
index 582670d9e1..a6bea7db64 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h
@@ -359,7 +359,7 @@ private:
/// {
/// if (instanceType == ADDON_INSTANCE_AUDIODECODER)
/// {
-/// kodi::Log(ADDON_LOG_NOTICE, "Creating my audio decoder");
+/// kodi::Log(ADDON_LOG_INFO, "Creating my audio decoder");
/// addonInstance = new CMyAudioDecoder(instance, version);
/// return ADDON_STATUS_OK;
/// }
@@ -414,7 +414,7 @@ public:
/// const std::string& version,
/// KODI_HANDLE& addonInstance)
/// {
- /// kodi::Log(ADDON_LOG_NOTICE, "Creating my audio decoder");
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my audio decoder");
/// addonInstance = new CMyAudioDecoder(instance, version);
/// return ADDON_STATUS_OK;
/// }
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
index 731ede87ec..9a869c1705 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioEncoder.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/AudioEncoder.h
@@ -131,7 +131,7 @@ namespace addon
/// {
/// if (instanceType == ADDON_INSTANCE_AUDIOENCODER)
/// {
-/// kodi::Log(ADDON_LOG_NOTICE, "Creating my audio encoder instance");
+/// kodi::Log(ADDON_LOG_INFO, "Creating my audio encoder instance");
/// addonInstance = new CMyAudioEncoder(instance, version);
/// return ADDON_STATUS_OK;
/// }
@@ -185,7 +185,7 @@ public:
/// const std::string& version,
/// KODI_HANDLE& addonInstance)
/// {
- /// kodi::Log(ADDON_LOG_NOTICE, "Creating my audio encoder instance");
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my audio encoder instance");
/// addonInstance = new CMyAudioEncoder(instance, version);
/// return ADDON_STATUS_OK;
/// }
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
index fd4748fbf0..a57def3add 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/CMakeLists.txt
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/CMakeLists.txt
@@ -4,7 +4,6 @@ set(HEADERS AudioDecoder.h
ImageDecoder.h
Inputstream.h
Peripheral.h
- PeripheralUtils.h
PVR.h
Screensaver.h
VFS.h
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
index a53f1e72b0..3dca94d022 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h
@@ -9,12 +9,14 @@
#pragma once
#include "../AddonBase.h"
+#include "../c-api/addon-instance/game.h"
-#ifdef BUILD_KODI_ADDON
-#include "XBMC_vkeys.h"
-#else
-#include "input/XBMC_vkeys.h"
-#endif
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace addon
+{
//==============================================================================
/// @addtogroup cpp_kodi_addon_game
@@ -26,824 +28,25 @@
/// could possible through the Game API.
///
-namespace kodi
-{
-namespace addon
-{
-class CInstanceGame;
-}
-} // namespace kodi
-
-extern "C"
-{
-
//==============================================================================
-/// \defgroup cpp_kodi_addon_game_Defs Definitions, structures and enumerators
-/// \ingroup cpp_kodi_addon_game
+/// @defgroup cpp_kodi_addon_game_Defs Definitions, structures and enumerators
+/// @ingroup cpp_kodi_addon_game
/// @brief **Game add-on instance definition values**
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// \ingroup cpp_kodi_addon_game_Defs
-/// @brief **Port ID used when topology is unknown**
-#define DEFAULT_PORT_ID "1"
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// \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;
-} ATTRIBUTE_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;
-} ATTRIBUTE_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 to used 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;
-} ATTRIBUTE_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;
-} ATTRIBUTE_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;
-} ATTRIBUTE_PACKED game_stream_hw_framebuffer_properties;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief **Hardware framebuffer buffer**
-///
-typedef struct game_stream_hw_framebuffer_buffer
-{
- /// @brief
- uintptr_t framebuffer;
-} ATTRIBUTE_PACKED game_stream_hw_framebuffer_buffer;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief **Hardware framebuffer packet**
-///
-typedef struct game_stream_hw_framebuffer_packet
-{
- /// @brief
- uintptr_t framebuffer;
-} ATTRIBUTE_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;
-} ATTRIBUTE_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;
- };
-} ATTRIBUTE_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;
- };
-} ATTRIBUTE_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;
- };
-} ATTRIBUTE_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**
+/// @defgroup cpp_kodi_addon_game_Defs_InputTypes_GameControllerLayout class GameControllerLayout
+/// @ingroup cpp_kodi_addon_game_Defs_InputTypes
+/// @brief Data of layouts for known controllers.
///
-//@{
-
-//==============================================================================
-/// @brief
-typedef enum GAME_INPUT_EVENT_SOURCE
+/// Used on @ref kodi::addon::CInstanceGame::SetControllerLayouts().
+///@{
+class GameControllerLayout
{
- /// @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;
-} ATTRIBUTE_PACKED game_controller_layout;
- /*! \endcond */
-
-//==============================================================================
-/// @brief
-struct AddonGameControllerLayout
-{
- /*! \cond PRIVATE */
- explicit AddonGameControllerLayout() = default;
- AddonGameControllerLayout(const game_controller_layout& layout)
+public:
+ /*! @cond PRIVATE */
+ explicit GameControllerLayout() = default;
+ GameControllerLayout(const game_controller_layout& layout)
{
controller_id = layout.controller_id;
provides_input = layout.provides_input;
@@ -864,450 +67,63 @@ struct AddonGameControllerLayout
for (unsigned int i = 0; i < layout.motor_count; ++i)
motors.push_back(layout.motors[i]);
}
- /*! \endcond */
+ /*! @endcond */
- /// @brief
+ /// @brief Controller identifier.
std::string controller_id;
- /// @brief False for multitaps
+ /// @brief Provides input.
+ ///
+ /// False for multitaps
bool provides_input;
- /// @brief
+ /// @brief Digital buttons.
std::vector<std::string> digital_buttons;
- /// @brief
+ /// @brief Analog buttons.
std::vector<std::string> analog_buttons;
- /// @brief
+ /// @brief Analog sticks.
std::vector<std::string> analog_sticks;
- /// @brief
+ /// @brief Accelerometers.
std::vector<std::string> accelerometers;
- /// @brief
+ /// @brief Keys.
std::vector<std::string> keys;
- /// @brief
+ /// @brief Relative pointers.
std::vector<std::string> rel_pointers;
- /// @brief
+ /// @brief Absolute pointers.
std::vector<std::string> abs_pointers;
- /// @brief
+ /// @brief Motors.
std::vector<std::string> motors;
};
+///@}
//------------------------------------------------------------------------------
-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
- game_input_port* available_ports;
-
- /// @brief
- unsigned int port_count;
-} ATTRIBUTE_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
- game_input_device* accepted_devices;
-
- /// @brief
- unsigned int device_count;
-} ATTRIBUTE_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;
-} ATTRIBUTE_PACKED game_input_topology;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_digital_button_event
-{
- /// @brief
- bool pressed;
-} ATTRIBUTE_PACKED game_digital_button_event;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_analog_button_event
-{
- /// @brief
- float magnitude;
-} ATTRIBUTE_PACKED game_analog_button_event;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_axis_event
-{
- /// @brief
- float position;
-} ATTRIBUTE_PACKED game_axis_event;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_analog_stick_event
-{
- /// @brief
- float x;
-
- /// @brief
- float y;
-} ATTRIBUTE_PACKED game_analog_stick_event;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_accelerometer_event
-{
- /// @brief
- float x;
-
- /// @brief
- float y;
-
- /// @brief
- float z;
-} ATTRIBUTE_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;
-} ATTRIBUTE_PACKED game_key_event;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_rel_pointer_event
-{
- /// @brief
- int x;
-
- /// @brief
- int y;
-} ATTRIBUTE_PACKED game_rel_pointer_event;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_abs_pointer_event
-{
- /// @brief
- bool pressed;
-
- /// @brief
- float x;
-
- /// @brief
- float y;
-} ATTRIBUTE_PACKED game_abs_pointer_event;
-//------------------------------------------------------------------------------
-
-//==============================================================================
-/// @brief
-typedef struct game_motor_event
-{
- /// @brief
- float magnitude;
-} ATTRIBUTE_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;
- };
-} ATTRIBUTE_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 AddonProps_Game game_client_properties;
-
-/*! 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)(void* kodiInstance);
- void* (*OpenStream)(void*, const game_stream_properties*);
- bool (*GetStreamBuffer)(void*, void*, unsigned int, unsigned int, game_stream_buffer*);
- void (*AddStreamData)(void*, void*, const game_stream_packet*);
- void (*ReleaseStreamBuffer)(void*, void*, game_stream_buffer*);
- void (*CloseStream)(void*, void*);
- game_proc_address_t (*HwGetProcAddress)(void* kodiInstance, const char* symbol);
- bool (*InputEvent)(void* kodiInstance, const game_input_event* event);
-} AddonToKodiFuncTable_Game;
-
-/*!
- * @brief Game function hooks
- *
- * Not to be used outside this header.
- */
-typedef struct KodiToAddonFuncTable_Game
-{
- kodi::addon::CInstanceGame* addonInstance;
-
- GAME_ERROR(__cdecl* LoadGame)(const AddonInstance_Game*, const char*);
- GAME_ERROR(__cdecl* LoadGameSpecial)
- (const AddonInstance_Game*, SPECIAL_GAME_TYPE, const char**, size_t);
- GAME_ERROR(__cdecl* LoadStandalone)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* UnloadGame)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* GetGameTiming)(const AddonInstance_Game*, game_system_timing*);
- GAME_REGION(__cdecl* GetRegion)(const AddonInstance_Game*);
- bool(__cdecl* RequiresGameLoop)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* RunFrame)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* Reset)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* HwContextReset)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* HwContextDestroy)(const AddonInstance_Game*);
- bool(__cdecl* HasFeature)(const AddonInstance_Game*, const char*, const char*);
- game_input_topology*(__cdecl* GetTopology)(const AddonInstance_Game*);
- void(__cdecl* FreeTopology)(const AddonInstance_Game*, game_input_topology*);
- void(__cdecl* SetControllerLayouts)(const AddonInstance_Game*,
- const game_controller_layout*,
- unsigned int);
- bool(__cdecl* EnableKeyboard)(const AddonInstance_Game*, bool, const char*);
- bool(__cdecl* EnableMouse)(const AddonInstance_Game*, bool, const char*);
- bool(__cdecl* ConnectController)(const AddonInstance_Game*, bool, const char*, const char*);
- bool(__cdecl* InputEvent)(const AddonInstance_Game*, const game_input_event*);
- size_t(__cdecl* SerializeSize)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* Serialize)(const AddonInstance_Game*, uint8_t*, size_t);
- GAME_ERROR(__cdecl* Deserialize)(const AddonInstance_Game*, const uint8_t*, size_t);
- GAME_ERROR(__cdecl* CheatReset)(const AddonInstance_Game*);
- GAME_ERROR(__cdecl* GetMemory)(const AddonInstance_Game*, GAME_MEMORY, uint8_t**, size_t*);
- GAME_ERROR(__cdecl* SetCheat)(const AddonInstance_Game*, unsigned int, bool, const char*);
-} KodiToAddonFuncTable_Game;
-
-/*!
- * @brief Game instance
- *
- * Not to be used outside this header.
- */
-typedef struct AddonInstance_Game
-{
- AddonProps_Game props;
- AddonToKodiFuncTable_Game toKodi;
- KodiToAddonFuncTable_Game toAddon;
-} AddonInstance_Game;
-
-} /* extern "C" */
-
-namespace kodi
-{
-namespace addon
-{
-
//==============================================================================
-///
-/// \addtogroup cpp_kodi_addon_game
-/// @brief \cpp_class{ kodi::addon::CInstanceGame }
-/// **Game add-on instance**
+/// @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 ATTRIBUTE_HIDDEN 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.
@@ -1354,29 +170,25 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Destructor
///
~CInstanceGame() override = default;
//----------------------------------------------------------------------------
//============================================================================
- ///
- /// @brief **Callback to Kodi Function**<br>The path of the game client being loaded.
+ /// @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;
- }
+ std::string GameClientDllPath() const { return m_instanceData->props->game_client_dll_path; }
//----------------------------------------------------------------------------
//============================================================================
- ///
- /// @brief **Callback to Kodi Function**<br>Paths to proxy DLLs used to load the game client.
+ /// @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
@@ -1385,18 +197,18 @@ public:
///
bool ProxyDllPaths(std::vector<std::string>& paths)
{
- for (unsigned int i = 0; i < m_instanceData->props.proxy_dll_count; ++i)
+ 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]);
+ 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**<br>The "system" directories of the frontend
+ /// @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.
@@ -1407,18 +219,18 @@ public:
///
bool ResourceDirectories(std::vector<std::string>& dirs)
{
- for (unsigned int i = 0; i < m_instanceData->props.resource_directory_count; ++i)
+ 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]);
+ 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**<br>The writable directory of the frontend
+ /// @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,
@@ -1428,29 +240,23 @@ public:
///
/// @remarks Only called from addon itself
///
- std::string ProfileDirectory() const
- {
- return m_instanceData->props.profile_directory;
- }
+ std::string ProfileDirectory() const { return m_instanceData->props->profile_directory; }
//----------------------------------------------------------------------------
//============================================================================
- ///
- /// @brief **Callback to Kodi Function**<br>The value of the <supports_vfs> property from addon.xml
+ /// @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;
- }
+ bool SupportsVFS() const { return m_instanceData->props->supports_vfs; }
//----------------------------------------------------------------------------
//============================================================================
- ///
- /// @brief **Callback to Kodi Function**<br>The extensions in the <extensions> property from addon.xml
+ /// @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
@@ -1459,16 +265,16 @@ public:
///
bool Extensions(std::vector<std::string>& extensions)
{
- for (unsigned int i = 0; i < m_instanceData->props.extension_count; ++i)
+ 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]);
+ if (m_instanceData->props->extensions[i] != nullptr)
+ extensions.push_back(m_instanceData->props->extensions[i]);
}
return !extensions.empty();
}
//----------------------------------------------------------------------------
- //@}
+ ///@}
//--==----==----==----==----==----==----==----==----==----==----==----==----==--
@@ -1481,10 +287,19 @@ public:
/// 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
@@ -1497,7 +312,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Load a game that requires multiple files
///
/// @param[in] type The game type
@@ -1511,7 +325,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Begin playing without a game file
///
/// If the add-on supports standalone mode, it must add the <supports_standalone>
@@ -1528,7 +341,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Unload the current game
///
/// Unloads a currently loaded game
@@ -1542,7 +354,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Get timing information about the loaded game
///
/// @param[out] timing_info The info structure to fill
@@ -1556,7 +367,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Get region of the loaded game
///
/// @return the region, or @ref GAME_REGION_UNKNOWN if unknown or no game is loaded
@@ -1568,7 +378,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @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
@@ -1583,7 +392,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @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
@@ -1595,7 +403,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Reset the current game
///
/// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was reset
@@ -1607,19 +414,18 @@ public:
//----------------------------------------------------------------------------
//==========================================================================
- ///
- /// @brief **Callback to Kodi Function**<br>Requests the frontend to stop the current game
+ /// @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); }
+ 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 }
+ /// @brief @cpp_class{ kodi::addon::CInstanceGame::CStream }
/// **Game stream handler**
///
/// This class will be integrated into the addon, which can then open it if
@@ -1627,7 +433,7 @@ public:
///
///
/// @note Callback to Kodi class
- //@{
+ ///@{
class CStream
{
public:
@@ -1644,7 +450,6 @@ public:
}
//==========================================================================
- ///
/// @ingroup cpp_kodi_addon_game_Operation_CStream
/// @brief Create a stream for gameplay data
///
@@ -1665,15 +470,14 @@ public:
}
AddonToKodiFuncTable_Game& cb =
- static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance)
- ->m_instanceData->toKodi;
+ *static_cast<CInstanceGame*>(CAddonBase::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
///
@@ -1685,15 +489,14 @@ public:
return;
AddonToKodiFuncTable_Game& cb =
- static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance)
- ->m_instanceData->toKodi;
+ *static_cast<CInstanceGame*>(CAddonBase::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
///
@@ -1702,7 +505,7 @@ public:
/// @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().
+ /// @note If this returns true, buffer must be freed using @ref ReleaseBuffer().
///
/// @remarks Only called from addon itself
///
@@ -1712,14 +515,13 @@ public:
return false;
AddonToKodiFuncTable_Game& cb =
- static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance)
- ->m_instanceData->toKodi;
+ *static_cast<CInstanceGame*>(CAddonBase::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
///
@@ -1733,14 +535,13 @@ public:
return;
AddonToKodiFuncTable_Game& cb =
- static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance)
- ->m_instanceData->toKodi;
+ *static_cast<CInstanceGame*>(CAddonBase::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
///
@@ -1754,14 +555,13 @@ public:
return;
AddonToKodiFuncTable_Game& cb =
- static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance)
- ->m_instanceData->toKodi;
+ *static_cast<CInstanceGame*>(CAddonBase::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
///
@@ -1773,11 +573,11 @@ public:
//--------------------------------------------------------------------------
private:
- void* m_handle = nullptr;
+ KODI_GAME_STREAM_HANDLE m_handle = nullptr;
};
- //@}
+ ///@}
- //@}
+ ///@}
//--==----==----==----==----==----==----==----==----==----==----==----==----==--
@@ -1787,10 +587,19 @@ public:
/// @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.
@@ -1804,7 +613,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Called before the context is destroyed
///
/// Resources can be deinitialized at this step.
@@ -1817,7 +625,6 @@ public:
}
//============================================================================
- ///
/// @brief **Callback to Kodi Function**<br>Get a symbol from the hardware context
///
/// @param[in] sym The symbol's name
@@ -1828,24 +635,32 @@ public:
///
game_proc_address_t HwGetProcAddress(const char* sym)
{
- return m_instanceData->toKodi.HwGetProcAddress(m_instanceData->toKodi.kodiInstance, 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
@@ -1864,7 +679,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Get the input topology that specifies which controllers can be connected
///
/// @return The input topology, or null to use the default
@@ -1882,18 +696,16 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @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
@@ -1901,13 +713,12 @@ public:
/// 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<AddonGameControllerLayout>& controllers)
+ 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
@@ -1922,7 +733,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Enable/disable mouse input using the specified controller
///
/// @param[in] enable True to enable input, false otherwise
@@ -1937,7 +747,6 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
/// @brief Connect/disconnect a controller to a port on the virtual game console
///
/// @param[in] connect True to connect a controller, false to disconnect
@@ -1989,7 +798,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Notify the add-on of an input event
///
/// @param[in] event The input event
@@ -2003,37 +811,44 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @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
+ /// - @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);
+ 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
@@ -2045,7 +860,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Serialize the state of the game
///
/// @param[in] data The buffer receiving the serialized game data
@@ -2060,7 +874,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Deserialize the game from the given state
///
/// @param[in] data A buffer containing the game's new state
@@ -2074,20 +887,28 @@ public:
}
//----------------------------------------------------------------------------
- //@}
+ ///@}
//--==----==----==----==----==----==----==----==----==----==----==----==----==--
//============================================================================
- ///
/// @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
@@ -2099,7 +920,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Get a region of memory
///
/// @param[in] type The type of memory to retrieve
@@ -2115,7 +935,6 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- ///
/// @brief Set a cheat code
///
/// @param[in] index
@@ -2130,7 +949,7 @@ public:
}
//----------------------------------------------------------------------------
- //@}
+ ///@}
private:
void SetAddonStruct(KODI_HANDLE instance)
@@ -2140,44 +959,44 @@ private:
"allowed, table must be given from Kodi!");
m_instanceData = static_cast<AddonInstance_Game*>(instance);
- m_instanceData->toAddon.addonInstance = this;
-
- m_instanceData->toAddon.LoadGame = ADDON_LoadGame;
- m_instanceData->toAddon.LoadGameSpecial = ADDON_LoadGameSpecial;
- m_instanceData->toAddon.LoadStandalone = ADDON_LoadStandalone;
- m_instanceData->toAddon.UnloadGame = ADDON_UnloadGame;
- m_instanceData->toAddon.GetGameTiming = ADDON_GetGameTiming;
- m_instanceData->toAddon.GetRegion = ADDON_GetRegion;
- m_instanceData->toAddon.RequiresGameLoop = ADDON_RequiresGameLoop;
- m_instanceData->toAddon.RunFrame = ADDON_RunFrame;
- m_instanceData->toAddon.Reset = ADDON_Reset;
-
- m_instanceData->toAddon.HwContextReset = ADDON_HwContextReset;
- m_instanceData->toAddon.HwContextDestroy = ADDON_HwContextDestroy;
-
- m_instanceData->toAddon.HasFeature = ADDON_HasFeature;
- m_instanceData->toAddon.GetTopology = ADDON_GetTopology;
- m_instanceData->toAddon.FreeTopology = ADDON_FreeTopology;
- m_instanceData->toAddon.SetControllerLayouts = ADDON_SetControllerLayouts;
- m_instanceData->toAddon.EnableKeyboard = ADDON_EnableKeyboard;
- m_instanceData->toAddon.EnableMouse = ADDON_EnableMouse;
- m_instanceData->toAddon.ConnectController = ADDON_ConnectController;
- m_instanceData->toAddon.InputEvent = ADDON_InputEvent;
-
- m_instanceData->toAddon.SerializeSize = ADDON_SerializeSize;
- m_instanceData->toAddon.Serialize = ADDON_Serialize;
- m_instanceData->toAddon.Deserialize = ADDON_Deserialize;
-
- m_instanceData->toAddon.CheatReset = ADDON_CheatReset;
- m_instanceData->toAddon.GetMemory = ADDON_GetMemory;
- m_instanceData->toAddon.SetCheat = ADDON_SetCheat;
+ m_instanceData->toAddon->addonInstance = this;
+
+ m_instanceData->toAddon->LoadGame = ADDON_LoadGame;
+ m_instanceData->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial;
+ m_instanceData->toAddon->LoadStandalone = ADDON_LoadStandalone;
+ m_instanceData->toAddon->UnloadGame = ADDON_UnloadGame;
+ m_instanceData->toAddon->GetGameTiming = ADDON_GetGameTiming;
+ m_instanceData->toAddon->GetRegion = ADDON_GetRegion;
+ m_instanceData->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop;
+ m_instanceData->toAddon->RunFrame = ADDON_RunFrame;
+ m_instanceData->toAddon->Reset = ADDON_Reset;
+
+ m_instanceData->toAddon->HwContextReset = ADDON_HwContextReset;
+ m_instanceData->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
+
+ m_instanceData->toAddon->HasFeature = ADDON_HasFeature;
+ m_instanceData->toAddon->GetTopology = ADDON_GetTopology;
+ m_instanceData->toAddon->FreeTopology = ADDON_FreeTopology;
+ m_instanceData->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts;
+ m_instanceData->toAddon->EnableKeyboard = ADDON_EnableKeyboard;
+ m_instanceData->toAddon->EnableMouse = ADDON_EnableMouse;
+ m_instanceData->toAddon->ConnectController = ADDON_ConnectController;
+ m_instanceData->toAddon->InputEvent = ADDON_InputEvent;
+
+ m_instanceData->toAddon->SerializeSize = ADDON_SerializeSize;
+ m_instanceData->toAddon->Serialize = ADDON_Serialize;
+ m_instanceData->toAddon->Deserialize = ADDON_Deserialize;
+
+ m_instanceData->toAddon->CheatReset = ADDON_CheatReset;
+ m_instanceData->toAddon->GetMemory = ADDON_GetMemory;
+ m_instanceData->toAddon->SetCheat = ADDON_SetCheat;
}
// --- Game operations ---------------------------------------------------------
inline static GAME_ERROR ADDON_LoadGame(const AddonInstance_Game* instance, const char* url)
{
- return instance->toAddon.addonInstance->LoadGame(url);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadGame(url);
}
inline static GAME_ERROR ADDON_LoadGameSpecial(const AddonInstance_Game* instance,
@@ -2192,43 +1011,45 @@ private:
urlList.push_back(urls[i]);
}
- return instance->toAddon.addonInstance->LoadGameSpecial(type, urlList);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->LoadGameSpecial(type, urlList);
}
inline static GAME_ERROR ADDON_LoadStandalone(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->LoadStandalone();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadStandalone();
}
inline static GAME_ERROR ADDON_UnloadGame(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->UnloadGame();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->UnloadGame();
}
inline static GAME_ERROR ADDON_GetGameTiming(const AddonInstance_Game* instance,
game_system_timing* timing_info)
{
- return instance->toAddon.addonInstance->GetGameTiming(*timing_info);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->GetGameTiming(*timing_info);
}
inline static GAME_REGION ADDON_GetRegion(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->GetRegion();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetRegion();
}
inline static bool ADDON_RequiresGameLoop(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->RequiresGameLoop();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RequiresGameLoop();
}
inline static GAME_ERROR ADDON_RunFrame(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->RunFrame();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RunFrame();
}
inline static GAME_ERROR ADDON_Reset(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->Reset();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Reset();
}
@@ -2236,12 +1057,12 @@ private:
inline static GAME_ERROR ADDON_HwContextReset(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->HwContextReset();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextReset();
}
inline static GAME_ERROR ADDON_HwContextDestroy(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->HwContextDestroy();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextDestroy();
}
@@ -2251,18 +1072,19 @@ private:
const char* controller_id,
const char* feature_name)
{
- return instance->toAddon.addonInstance->HasFeature(controller_id, 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 instance->toAddon.addonInstance->GetTopology();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetTopology();
}
inline static void ADDON_FreeTopology(const AddonInstance_Game* instance,
game_input_topology* topology)
{
- instance->toAddon.addonInstance->FreeTopology(topology);
+ static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->FreeTopology(topology);
}
inline static void ADDON_SetControllerLayouts(const AddonInstance_Game* instance,
@@ -2272,25 +1094,28 @@ private:
if (controllers == nullptr)
return;
- std::vector<AddonGameControllerLayout> controllerList;
+ std::vector<GameControllerLayout> controllerList;
for (unsigned int i = 0; i < controller_count; ++i)
controllerList.push_back(controllers[i]);
- instance->toAddon.addonInstance->SetControllerLayouts(controllerList);
+ static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->SetControllerLayouts(controllerList);
}
inline static bool ADDON_EnableKeyboard(const AddonInstance_Game* instance,
bool enable,
const char* controller_id)
{
- return instance->toAddon.addonInstance->EnableKeyboard(enable, 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 instance->toAddon.addonInstance->EnableMouse(enable, controller_id);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->EnableMouse(enable, controller_id);
}
inline static bool ADDON_ConnectController(const AddonInstance_Game* instance,
@@ -2298,13 +1123,14 @@ private:
const char* port_address,
const char* controller_id)
{
- return instance->toAddon.addonInstance->ConnectController(connect, port_address, 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 instance->toAddon.addonInstance->InputEvent(*event);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->InputEvent(*event);
}
@@ -2312,21 +1138,21 @@ private:
inline static size_t ADDON_SerializeSize(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->SerializeSize();
+ 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 instance->toAddon.addonInstance->Serialize(data, 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 instance->toAddon.addonInstance->Deserialize(data, size);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Deserialize(data, size);
}
@@ -2334,7 +1160,7 @@ private:
inline static GAME_ERROR ADDON_CheatReset(const AddonInstance_Game* instance)
{
- return instance->toAddon.addonInstance->CheatReset();
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->CheatReset();
}
inline static GAME_ERROR ADDON_GetMemory(const AddonInstance_Game* instance,
@@ -2342,7 +1168,8 @@ private:
uint8_t** data,
size_t* size)
{
- return instance->toAddon.addonInstance->GetMemory(type, *data, *size);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->GetMemory(type, *data, *size);
}
inline static GAME_ERROR ADDON_SetCheat(const AddonInstance_Game* instance,
@@ -2350,7 +1177,8 @@ private:
bool enabled,
const char* code)
{
- return instance->toAddon.addonInstance->SetCheat(index, enabled, code);
+ return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
+ ->SetCheat(index, enabled, code);
}
AddonInstance_Game* m_instanceData;
@@ -2358,3 +1186,5 @@ private:
} /* 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
index e41e5ef3fa..7aeef7bf14 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/ImageDecoder.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/ImageDecoder.h
@@ -177,7 +177,7 @@ namespace addon
/// {
/// if (instanceType == ADDON_INSTANCE_IMAGEDECODER)
/// {
-/// kodi::Log(ADDON_LOG_NOTICE, "Creating my image decoder instance");
+/// kodi::Log(ADDON_LOG_INFO, "Creating my image decoder instance");
/// addonInstance = new CMyImageDecoder(instance, version);
/// return ADDON_STATUS_OK;
/// }
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
index 0bca8e2d75..18bbbef3e4 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h
@@ -364,7 +364,7 @@ namespace addon
/// {
/// if (instanceType == ADDON_INSTANCE_PVR)
/// {
-/// kodi::Log(ADDON_LOG_NOTICE, "Creating my PVR client instance");
+/// kodi::Log(ADDON_LOG_INFO, "Creating my PVR client instance");
/// addonInstance = new CMyPVRClient(instance, version);
/// return ADDON_STATUS_OK;
/// }
@@ -484,7 +484,7 @@ public:
/// const std::string& version,
/// KODI_HANDLE& addonInstance)
/// {
- /// kodi::Log(ADDON_LOG_NOTICE, "Creating my PVR client instance");
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my PVR client instance");
/// addonInstance = new CMyPVRClient(instance, version);
/// return ADDON_STATUS_OK;
/// }
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
index 2067d51553..46060a8f1c 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h
@@ -9,839 +9,899 @@
#pragma once
#include "../AddonBase.h"
+#include "peripheral/PeripheralUtils.h"
-namespace kodi { namespace addon { class CInstancePeripheral; }}
-
-/* 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)
-
-extern "C"
-{
-
- /// @name Peripheral types
- ///{
-
- /*!
- * @brief API error codes
- */
- typedef enum PERIPHERAL_ERROR
- {
- PERIPHERAL_NO_ERROR = 0, // no error occurred
- PERIPHERAL_ERROR_UNKNOWN = -1, // an unknown error occurred
- PERIPHERAL_ERROR_FAILED = -2, // the command failed
- PERIPHERAL_ERROR_INVALID_PARAMETERS = -3, // the parameters of the method are invalid for this operation
- PERIPHERAL_ERROR_NOT_IMPLEMENTED = -4, // the method that the frontend called is not implemented
- PERIPHERAL_ERROR_NOT_CONNECTED = -5, // no peripherals are connected
- PERIPHERAL_ERROR_CONNECTION_FAILED = -6, // peripherals are connected, but command was interrupted
- } PERIPHERAL_ERROR;
-
- /*!
- * @brief Peripheral types
- */
- typedef enum PERIPHERAL_TYPE
- {
- PERIPHERAL_TYPE_UNKNOWN,
- PERIPHERAL_TYPE_JOYSTICK,
- PERIPHERAL_TYPE_KEYBOARD,
- } PERIPHERAL_TYPE;
-
- /*!
- * @brief Information shared between peripherals
- */
- typedef struct PERIPHERAL_INFO
- {
- PERIPHERAL_TYPE type; /*!< @brief type of peripheral */
- char* name; /*!< @brief name of peripheral */
- uint16_t vendor_id; /*!< @brief vendor ID of peripheral, 0x0000 if unknown */
- uint16_t product_id; /*!< @brief product ID of peripheral, 0x0000 if unknown */
- unsigned int index; /*!< @brief the order in which the add-on identified this peripheral */
- } ATTRIBUTE_PACKED PERIPHERAL_INFO;
-
- /*!
- * @brief Peripheral add-on capabilities.
- */
- typedef struct PERIPHERAL_CAPABILITIES
- {
- bool provides_joysticks; /*!< @brief true if the add-on provides joysticks */
- bool provides_joystick_rumble;
- bool provides_joystick_power_off;
- bool provides_buttonmaps; /*!< @brief true if the add-on provides button maps */
- } ATTRIBUTE_PACKED PERIPHERAL_CAPABILITIES;
- ///}
-
- /// @name Event types
- ///{
-
- /*!
- * @brief Types of events that can be sent and received
- */
- typedef enum PERIPHERAL_EVENT_TYPE
- {
- PERIPHERAL_EVENT_TYPE_NONE, /*!< @brief unknown event */
- PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON, /*!< @brief state changed for joystick driver button */
- PERIPHERAL_EVENT_TYPE_DRIVER_HAT, /*!< @brief state changed for joystick driver hat */
- PERIPHERAL_EVENT_TYPE_DRIVER_AXIS, /*!< @brief state changed for joystick driver axis */
- PERIPHERAL_EVENT_TYPE_SET_MOTOR, /*!< @brief set the state for joystick rumble motor */
- } PERIPHERAL_EVENT_TYPE;
-
- /*!
- * @brief States a button can have
- */
- typedef enum JOYSTICK_STATE_BUTTON
- {
- JOYSTICK_STATE_BUTTON_UNPRESSED = 0x0, /*!< @brief button is released */
- JOYSTICK_STATE_BUTTON_PRESSED = 0x1, /*!< @brief button is pressed */
- } JOYSTICK_STATE_BUTTON;
-
- /*!
- * @brief States a D-pad (also called a hat) can have
- */
- typedef enum JOYSTICK_STATE_HAT
- {
- JOYSTICK_STATE_HAT_UNPRESSED = 0x0, /*!< @brief no directions are pressed */
- JOYSTICK_STATE_HAT_LEFT = 0x1, /*!< @brief only left is pressed */
- JOYSTICK_STATE_HAT_RIGHT = 0x2, /*!< @brief only right is pressed */
- JOYSTICK_STATE_HAT_UP = 0x4, /*!< @brief only up is pressed */
- JOYSTICK_STATE_HAT_DOWN = 0x8, /*!< @brief only down is pressed */
- JOYSTICK_STATE_HAT_LEFT_UP = JOYSTICK_STATE_HAT_LEFT | JOYSTICK_STATE_HAT_UP,
- JOYSTICK_STATE_HAT_LEFT_DOWN = JOYSTICK_STATE_HAT_LEFT | JOYSTICK_STATE_HAT_DOWN,
- JOYSTICK_STATE_HAT_RIGHT_UP = JOYSTICK_STATE_HAT_RIGHT | JOYSTICK_STATE_HAT_UP,
- JOYSTICK_STATE_HAT_RIGHT_DOWN = JOYSTICK_STATE_HAT_RIGHT | JOYSTICK_STATE_HAT_DOWN,
- } JOYSTICK_STATE_HAT;
-
- /*!
- * @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;
-
- /*!
- * @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;
- } ATTRIBUTE_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 */
- } ATTRIBUTE_PACKED JOYSTICK_INFO;
-
- /*!
- * @brief 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
- {
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN,
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON,
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION,
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS,
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR,
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY,
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON,
- JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION,
- } JOYSTICK_DRIVER_PRIMITIVE_TYPE;
-
- /*!
- * @brief Button primitive
- */
- typedef struct JOYSTICK_DRIVER_BUTTON
- {
- int index;
- } ATTRIBUTE_PACKED JOYSTICK_DRIVER_BUTTON;
-
- /*!
- * @brief Hat direction
- */
- typedef enum JOYSTICK_DRIVER_HAT_DIRECTION
- {
- JOYSTICK_DRIVER_HAT_UNKNOWN,
- JOYSTICK_DRIVER_HAT_LEFT,
- JOYSTICK_DRIVER_HAT_RIGHT,
- JOYSTICK_DRIVER_HAT_UP,
- JOYSTICK_DRIVER_HAT_DOWN,
- } JOYSTICK_DRIVER_HAT_DIRECTION;
-
- /*!
- * @brief Hat direction primitive
- */
- typedef struct JOYSTICK_DRIVER_HAT
- {
- int index;
- JOYSTICK_DRIVER_HAT_DIRECTION direction;
- } ATTRIBUTE_PACKED JOYSTICK_DRIVER_HAT;
-
- /*!
- * @brief Semiaxis direction
- */
- typedef enum JOYSTICK_DRIVER_SEMIAXIS_DIRECTION
- {
- JOYSTICK_DRIVER_SEMIAXIS_NEGATIVE = -1, /*!< @brief negative half of the axis */
- JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN = 0, /*!< @brief unknown direction */
- JOYSTICK_DRIVER_SEMIAXIS_POSITIVE = 1, /*!< @brief positive half of the axis */
- } JOYSTICK_DRIVER_SEMIAXIS_DIRECTION;
-
- /*!
- * @brief Semiaxis primitive
- */
- typedef struct JOYSTICK_DRIVER_SEMIAXIS
- {
- int index;
- int center;
- JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction;
- unsigned int range;
- } ATTRIBUTE_PACKED JOYSTICK_DRIVER_SEMIAXIS;
-
- /*!
- * @brief Motor primitive
- */
- typedef struct JOYSTICK_DRIVER_MOTOR
- {
- int index;
- } ATTRIBUTE_PACKED JOYSTICK_DRIVER_MOTOR;
-
- /*!
- * @brief Keyboard key primitive
- */
- typedef struct JOYSTICK_DRIVER_KEY
- {
- char keycode[16];
- } ATTRIBUTE_PACKED JOYSTICK_DRIVER_KEY;
-
- /*!
- * @brief Mouse buttons
- */
- typedef enum JOYSTICK_DRIVER_MOUSE_INDEX
- {
- JOYSTICK_DRIVER_MOUSE_INDEX_UNKNOWN,
- JOYSTICK_DRIVER_MOUSE_INDEX_LEFT,
- JOYSTICK_DRIVER_MOUSE_INDEX_RIGHT,
- JOYSTICK_DRIVER_MOUSE_INDEX_MIDDLE,
- JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON4,
- JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON5,
- JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_UP,
- JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_DOWN,
- JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_LEFT,
- 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;
- } ATTRIBUTE_PACKED JOYSTICK_DRIVER_MOUSE_BUTTON;
-
- /*!
- * @brief Relative pointer direction
- */
- typedef enum JOYSTICK_DRIVER_RELPOINTER_DIRECTION
- {
- JOYSTICK_DRIVER_RELPOINTER_UNKNOWN,
- JOYSTICK_DRIVER_RELPOINTER_LEFT,
- JOYSTICK_DRIVER_RELPOINTER_RIGHT,
- JOYSTICK_DRIVER_RELPOINTER_UP,
- JOYSTICK_DRIVER_RELPOINTER_DOWN,
- } JOYSTICK_DRIVER_RELPOINTER_DIRECTION;
-
- /*!
- * @brief Relative pointer direction primitive
- */
- typedef struct JOYSTICK_DRIVER_RELPOINTER
- {
- JOYSTICK_DRIVER_RELPOINTER_DIRECTION direction;
- } ATTRIBUTE_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;
- };
- } ATTRIBUTE_PACKED JOYSTICK_DRIVER_PRIMITIVE;
-
- /*!
- * @brief Controller feature
- *
- * Controller features are an abstraction over driver values. Each feature
- * maps to one or more driver primitives.
- */
- typedef enum JOYSTICK_FEATURE_TYPE
- {
- JOYSTICK_FEATURE_TYPE_UNKNOWN,
- JOYSTICK_FEATURE_TYPE_SCALAR,
- JOYSTICK_FEATURE_TYPE_ANALOG_STICK,
- JOYSTICK_FEATURE_TYPE_ACCELEROMETER,
- JOYSTICK_FEATURE_TYPE_MOTOR,
- JOYSTICK_FEATURE_TYPE_RELPOINTER,
- JOYSTICK_FEATURE_TYPE_ABSPOINTER,
- JOYSTICK_FEATURE_TYPE_WHEEL,
- JOYSTICK_FEATURE_TYPE_THROTTLE,
- JOYSTICK_FEATURE_TYPE_KEY,
- } JOYSTICK_FEATURE_TYPE;
-
- /*!
- * @brief Indices used to access a feature's driver primitives
- */
- typedef enum JOYSTICK_FEATURE_PRIMITIVE
- {
- // Scalar feature (a button, hat direction or semiaxis)
- JOYSTICK_SCALAR_PRIMITIVE = 0,
-
- // Analog stick
- JOYSTICK_ANALOG_STICK_UP = 0,
- JOYSTICK_ANALOG_STICK_DOWN = 1,
- JOYSTICK_ANALOG_STICK_RIGHT = 2,
- JOYSTICK_ANALOG_STICK_LEFT = 3,
-
- // Accelerometer
- JOYSTICK_ACCELEROMETER_POSITIVE_X = 0,
- JOYSTICK_ACCELEROMETER_POSITIVE_Y = 1,
- JOYSTICK_ACCELEROMETER_POSITIVE_Z = 2,
-
- // Motor
- JOYSTICK_MOTOR_PRIMITIVE = 0,
-
- // Wheel
- JOYSTICK_WHEEL_LEFT = 0,
- JOYSTICK_WHEEL_RIGHT = 1,
-
- // Throttle
- JOYSTICK_THROTTLE_UP = 0,
- JOYSTICK_THROTTLE_DOWN = 1,
-
- // Key
- JOYSTICK_KEY_PRIMITIVE = 0,
-
- // Mouse button
- JOYSTICK_MOUSE_BUTTON = 0,
-
- // Relative pointer direction
- JOYSTICK_RELPOINTER_UP = 0,
- JOYSTICK_RELPOINTER_DOWN = 1,
- JOYSTICK_RELPOINTER_RIGHT = 2,
- JOYSTICK_RELPOINTER_LEFT = 3,
-
- // 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];
- } ATTRIBUTE_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 */
- } ATTRIBUTE_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::addon::CInstancePeripheral* addonInstance;
-
- void (__cdecl* get_capabilities)(const AddonInstance_Peripheral* addonInstance, PERIPHERAL_CAPABILITIES* capabilities);
- PERIPHERAL_ERROR (__cdecl* perform_device_scan)(const AddonInstance_Peripheral* addonInstance, unsigned int* peripheral_count, PERIPHERAL_INFO** scan_results);
- void (__cdecl* free_scan_results)(const AddonInstance_Peripheral* addonInstance, unsigned int peripheral_count, PERIPHERAL_INFO* scan_results);
- PERIPHERAL_ERROR (__cdecl* get_events)(const AddonInstance_Peripheral* addonInstance, unsigned int* event_count, PERIPHERAL_EVENT** events);
- void (__cdecl* free_events)(const AddonInstance_Peripheral* addonInstance, unsigned int event_count, PERIPHERAL_EVENT* events);
- bool (__cdecl* send_event)(const AddonInstance_Peripheral* addonInstance, const PERIPHERAL_EVENT* event);
-
- /// @name Joystick operations
- ///{
- PERIPHERAL_ERROR (__cdecl* get_joystick_info)(const AddonInstance_Peripheral* addonInstance, unsigned int index, JOYSTICK_INFO* info);
- void (__cdecl* free_joystick_info)(const AddonInstance_Peripheral* addonInstance, JOYSTICK_INFO* info);
- PERIPHERAL_ERROR (__cdecl* get_features)(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick, const char* controller_id, unsigned int* feature_count, JOYSTICK_FEATURE** features);
- void (__cdecl* free_features)(const AddonInstance_Peripheral* addonInstance, unsigned int feature_count, JOYSTICK_FEATURE* features);
- PERIPHERAL_ERROR (__cdecl* map_features)(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick, const char* controller_id, unsigned int feature_count, const JOYSTICK_FEATURE* features);
- PERIPHERAL_ERROR (__cdecl* get_ignored_primitives)(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick, unsigned int* feature_count, JOYSTICK_DRIVER_PRIMITIVE** primitives);
- void (__cdecl* free_primitives)(const AddonInstance_Peripheral* addonInstance, unsigned int, JOYSTICK_DRIVER_PRIMITIVE* primitives);
- PERIPHERAL_ERROR (__cdecl* set_ignored_primitives)(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick, unsigned int primitive_count, const JOYSTICK_DRIVER_PRIMITIVE* primitives);
- void (__cdecl* save_button_map)(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick);
- void (__cdecl* revert_button_map)(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick);
- void (__cdecl* reset_button_map)(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick, const char* controller_id);
- void (__cdecl* power_off_joystick)(const AddonInstance_Peripheral* addonInstance, unsigned int index);
- ///}
- } KodiToAddonFuncTable_Peripheral;
-
- typedef struct AddonInstance_Peripheral
- {
- AddonProps_Peripheral props;
- AddonToKodiFuncTable_Peripheral toKodi;
- KodiToAddonFuncTable_Peripheral toAddon;
- } AddonInstance_Peripheral;
-
-} /* extern "C" */
-
+#ifdef __cplusplus
namespace kodi
{
namespace addon
{
- class ATTRIBUTE_HIDDEN CInstancePeripheral : public IAddonInstance
+//##############################################################################
+/// @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(KODI_HANDLE instance, const std::string& version);
+///
+/// void GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities) override;
+/// ...
+/// };
+///
+/// CMyPeripheralAddon::CMyPeripheralAddon(KODI_HANDLE instance, const std::string& version)
+/// : CInstancePeripheral(instance, version)
+/// {
+/// ...
+/// }
+///
+/// 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(int instanceType,
+/// const std::string& instanceID,
+/// KODI_HANDLE instance,
+/// const std::string& version,
+/// KODI_HANDLE& addonInstance) override;
+/// };
+///
+/// // If you use only one instance in your add-on, can be instanceType and
+/// // instanceID ignored
+/// ADDON_STATUS CMyAddon::CreateInstance(int instanceType,
+/// const std::string& instanceID,
+/// KODI_HANDLE instance,
+/// const std::string& version,
+/// KODI_HANDLE& addonInstance)
+/// {
+/// if (instanceType == ADDON_INSTANCE_PERIPHERAL)
+/// {
+/// kodi::Log(ADDON_LOG_INFO, "Creating my peripheral addon");
+/// addonInstance = new CMyPeripheralAddon(instance, version);
+/// 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 ATTRIBUTE_HIDDEN CInstancePeripheral : public IAddonInstance
+{
+public:
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_peripheral
+ /// @brief %Peripheral class constructor.
+ ///
+ /// Used by an add-on that only supports peripheral.
+ ///
+ CInstancePeripheral()
+ : IAddonInstance(ADDON_INSTANCE_PERIPHERAL, GetKodiTypeVersion(ADDON_INSTANCE_PERIPHERAL))
{
- public:
- CInstancePeripheral()
- : IAddonInstance(ADDON_INSTANCE_PERIPHERAL, GetKodiTypeVersion(ADDON_INSTANCE_PERIPHERAL))
- {
- if (CAddonBase::m_interface->globalSingleInstance != nullptr)
- throw std::logic_error("kodi::addon::CInstancePeripheral: Creation of more as one in single instance way is not allowed!");
-
- SetAddonStruct(CAddonBase::m_interface->firstKodiInstance);
- CAddonBase::m_interface->globalSingleInstance = this;
- }
+ if (CAddonBase::m_interface->globalSingleInstance != nullptr)
+ throw std::logic_error("kodi::addon::CInstancePeripheral: Creation of more as one in single "
+ "instance way is not allowed!");
+
+ SetAddonStruct(CAddonBase::m_interface->firstKodiInstance);
+ CAddonBase::m_interface->globalSingleInstance = this;
+ }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_addon_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>.
+ /// @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 CMyPeripheralAddon : public kodi::addon::CInstancePeripheral
+ /// {
+ /// public:
+ /// CMyPeripheralAddon(KODI_HANDLE instance, const std::string& kodiVersion)
+ /// : kodi::addon::CInstancePeripheral(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 peripheral");
+ /// addonInstance = new CMyPeripheralAddon(instance, version);
+ /// return ADDON_STATUS_OK;
+ /// }
+ /// ~~~~~~~~~~~~~
+ ///
+ explicit CInstancePeripheral(KODI_HANDLE instance, const std::string& kodiVersion = "")
+ : IAddonInstance(ADDON_INSTANCE_PERIPHERAL,
+ !kodiVersion.empty() ? kodiVersion
+ : GetKodiTypeVersion(ADDON_INSTANCE_PERIPHERAL))
+ {
+ if (CAddonBase::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());
+ }
+ //----------------------------------------------------------------------------
- explicit CInstancePeripheral(KODI_HANDLE instance, const std::string& kodiVersion = "")
- : IAddonInstance(ADDON_INSTANCE_PERIPHERAL,
- !kodiVersion.empty() ? kodiVersion
- : GetKodiTypeVersion(ADDON_INSTANCE_PERIPHERAL))
- {
- if (CAddonBase::m_interface->globalSingleInstance != nullptr)
- throw std::logic_error("kodi::addon::CInstancePeripheral: Creation of multiple together with single instance way is not allowed!");
+ ///@}
- SetAddonStruct(instance);
- }
+private:
+ void SetAddonStruct(KODI_HANDLE instance)
+ {
+ if (instance == nullptr)
+ throw std::logic_error("kodi::addon::CInstancePeripheral: Creation with empty addon "
+ "structure not allowed, table must be given from Kodi!");
+
+ m_instanceData = static_cast<AddonInstance_Peripheral*>(instance);
+ m_instanceData->toAddon->addonInstance = this;
+
+ m_instanceData->toAddon->get_capabilities = ADDON_GetCapabilities;
+ m_instanceData->toAddon->perform_device_scan = ADDON_PerformDeviceScan;
+ m_instanceData->toAddon->free_scan_results = ADDON_FreeScanResults;
+ m_instanceData->toAddon->get_events = ADDON_GetEvents;
+ m_instanceData->toAddon->free_events = ADDON_FreeEvents;
+ m_instanceData->toAddon->send_event = ADDON_SendEvent;
+
+ m_instanceData->toAddon->get_joystick_info = ADDON_GetJoystickInfo;
+ m_instanceData->toAddon->free_joystick_info = ADDON_FreeJoystickInfo;
+ m_instanceData->toAddon->get_features = ADDON_GetFeatures;
+ m_instanceData->toAddon->free_features = ADDON_FreeFeatures;
+ m_instanceData->toAddon->map_features = ADDON_MapFeatures;
+ m_instanceData->toAddon->get_ignored_primitives = ADDON_GetIgnoredPrimitives;
+ m_instanceData->toAddon->free_primitives = ADDON_FreePrimitives;
+ m_instanceData->toAddon->set_ignored_primitives = ADDON_SetIgnoredPrimitives;
+ m_instanceData->toAddon->save_button_map = ADDON_SaveButtonMap;
+ m_instanceData->toAddon->revert_button_map = ADDON_RevertButtonMap;
+ m_instanceData->toAddon->reset_button_map = ADDON_ResetButtonMap;
+ m_instanceData->toAddon->power_off_joystick = ADDON_PowerOffJoystick;
+ }
+
+ 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;
- ~CInstancePeripheral() override = default;
-
- /// @name Peripheral operations
- ///{
- /*!
- * @brief Get the list of features that this add-on provides
- * @param capabilities The add-on's capabilities.
- * @remarks Valid implementation required.
- *
- * 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.
- *
- */
- virtual void GetCapabilities(PERIPHERAL_CAPABILITIES &capabilities) { }
-
- /*!
- * @brief Perform a scan for joysticks
- * @param peripheral_count Assigned to the number of peripherals allocated
- * @param scan_results Assigned to allocated memory
- * @return PERIPHERAL_NO_ERROR if successful; peripherals must be freed using
- * FreeScanResults() in this case
- *
- * 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
- * TriggerScan() callback.
- */
- virtual PERIPHERAL_ERROR PerformDeviceScan(unsigned int* peripheral_count, PERIPHERAL_INFO** scan_results) { return PERIPHERAL_ERROR_NOT_IMPLEMENTED; }
-
- /*!
- * @brief Free the memory allocated in PerformDeviceScan()
- *
- * Must be called if PerformDeviceScan() returns PERIPHERAL_NO_ERROR.
- *
- * @param peripheral_count The number of events allocated for the events array
- * @param scan_results The array of allocated peripherals
- */
- virtual void FreeScanResults(unsigned int peripheral_count, PERIPHERAL_INFO* scan_results) { }
-
- /*!
- * @brief Get all events that have occurred since the last call to GetEvents()
- * @return PERIPHERAL_NO_ERROR if successful; events must be freed using
- * FreeEvents() in this case
- */
- virtual PERIPHERAL_ERROR GetEvents(unsigned int* event_count, PERIPHERAL_EVENT** events) { return PERIPHERAL_ERROR_NOT_IMPLEMENTED; }
-
- /*!
- * @brief Free the memory allocated in GetEvents()
- *
- * Must be called if GetEvents() returns PERIPHERAL_NO_ERROR.
- *
- * @param event_count The number of events allocated for the events array
- * @param events The array of allocated events
- */
- virtual void FreeEvents(unsigned int event_count, PERIPHERAL_EVENT* events) { }
-
- /*!
- * @brief Send an input event to the peripheral
- * @param event The input event
- * @return true if the event was handled, false otherwise
- */
- virtual bool SendEvent(const PERIPHERAL_EVENT* event) { return false; }
- ///}
-
- /// @name Joystick operations
- /*!
- * @note #define PERIPHERAL_ADDON_JOYSTICKS before including kodi_peripheral_dll.h
- * in the add-on if the add-on provides joysticks and add provides_joysticks="true"
- * to the kodi.peripheral extension point node in addon.xml.
- */
- ///{
- /*!
- * @brief Get extended info about an attached joystick
- * @param index The joystick's driver index
- * @param info The container for the allocated joystick info
- * @return PERIPHERAL_NO_ERROR if successful; array must be freed using
- * FreeJoystickInfo() in this case
- */
- virtual PERIPHERAL_ERROR GetJoystickInfo(unsigned int index, JOYSTICK_INFO* info) { return PERIPHERAL_ERROR_NOT_IMPLEMENTED; }
-
- /*!
- * @brief Free the memory allocated in GetJoystickInfo()
- */
- virtual void FreeJoystickInfo(JOYSTICK_INFO* info) { }
-
- /*!
- * @brief Get the features that allow translating the joystick into the controller profile
- * @param joystick The device's joystick properties; unknown values may be left at their default
- * @param controller_id The controller profile being requested, e.g. game.controller.default
- * @param feature_count The number of features allocated for the features array
- * @param features The array of allocated features
- * @return PERIPHERAL_NO_ERROR if successful; array must be freed using
- * FreeButtonMap() in this case
- */
- virtual PERIPHERAL_ERROR GetFeatures(const JOYSTICK_INFO* joystick, const char* controller_id,
- unsigned int* feature_count, JOYSTICK_FEATURE** features) { return PERIPHERAL_ERROR_NOT_IMPLEMENTED; }
-
- /*!
- * @brief Free the memory allocated in GetFeatures()
- *
- * Must be called if GetFeatures() returns PERIPHERAL_NO_ERROR.
- *
- * @param feature_count The number of features allocated for the features array
- * @param features The array of allocated features
- */
- virtual void FreeFeatures(unsigned int feature_count, JOYSTICK_FEATURE* features) { }
-
- /*!
- * @brief Add or update joystick features
- * @param joystick The device's joystick properties; unknown values may be left at their default
- * @param controller_id The game controller profile being updated
- * @param feature_count The number of features in the features array
- * @param features The array of features
- * @return PERIPHERAL_NO_ERROR if successful
- */
- virtual PERIPHERAL_ERROR MapFeatures(const JOYSTICK_INFO* joystick, const char* controller_id,
- unsigned int feature_count, const JOYSTICK_FEATURE* features) { return PERIPHERAL_ERROR_NOT_IMPLEMENTED; }
-
- /*!
- * @brief Get the driver primitives that should be ignored while mapping the device
- * @param joystick The device's joystick properties; unknown values may be left at their default
- * @param primitive_count The number of features allocated for the primitives array
- * @param primitives The array of allocated driver primitives to be ignored
- * @return PERIPHERAL_NO_ERROR if successful; array must be freed using
- * FreePrimitives() in this case
- */
- virtual PERIPHERAL_ERROR GetIgnoredPrimitives(const JOYSTICK_INFO* joystick,
- unsigned int* primitive_count,
- JOYSTICK_DRIVER_PRIMITIVE** primitives) { return PERIPHERAL_ERROR_NOT_IMPLEMENTED; }
-
- /*!
- * @brief Free the memory allocated in GetIgnoredPrimitives()
- *
- * Must be called if GetIgnoredPrimitives() returns PERIPHERAL_NO_ERROR.
- *
- * @param primitive_count The number of driver primitives allocated for the primitives array
- * @param primitives The array of allocated driver primitives
- */
- virtual void FreePrimitives(unsigned int primitive_count, JOYSTICK_DRIVER_PRIMITIVE* primitives) { }
-
- /*!
- * @brief Set the list of driver primitives that are ignored for the device
- * @param joystick The device's joystick properties; unknown values may be left at their default
- * @param primitive_count The number of driver features in the primitives array
- * @param primitives The array of driver primitives to ignore
- * @return PERIPHERAL_NO_ERROR if successful
- */
- virtual PERIPHERAL_ERROR SetIgnoredPrimitives(const JOYSTICK_INFO* joystick,
- unsigned int primitive_count,
- const JOYSTICK_DRIVER_PRIMITIVE* primitives) { return PERIPHERAL_ERROR_NOT_IMPLEMENTED; }
-
- /*!
- * @brief Save the button map for the given joystick
- * @param joystick The device's joystick properties
- */
- virtual void SaveButtonMap(const JOYSTICK_INFO* joystick) { }
-
- /*!
- * @brief Revert the button map to the last time it was loaded or committed to disk
- * @param joystick The device's joystick properties
- */
- virtual void RevertButtonMap(const JOYSTICK_INFO* joystick) { }
-
- /*!
- * @brief Reset the button map for the given joystick and controller profile ID
- * @param joystick The device's joystick properties
- * @param controller_id The game controller profile being reset
- */
- virtual void ResetButtonMap(const JOYSTICK_INFO* joystick, const char* controller_id) { }
-
- /*!
- * @brief Powers off the given joystick if supported
- * @param index The joystick's driver index
- */
- virtual void PowerOffJoystick(unsigned int index) { }
-
- const std::string AddonPath() const
+ 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)
{
- return m_instanceData->props.addon_path;
+ *peripheral_count = static_cast<unsigned int>(peripherals.size());
+ kodi::addon::Peripherals::ToStructs(peripherals, scan_results);
}
- const std::string UserPath() const
- {
- return m_instanceData->props.user_path;
- }
+ return err;
+ }
- /*!
- * @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);
- }
+ inline static void ADDON_FreeScanResults(const AddonInstance_Peripheral* addonInstance,
+ unsigned int peripheral_count,
+ PERIPHERAL_INFO* scan_results)
+ {
+ if (!addonInstance)
+ return;
- /*!
- * @brief Notify the frontend that button maps have changed
- *
- * @param[optional] deviceName The name of the device to refresh, or empty/null for all devices
- * @param[optional] controllerId 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());
- }
+ kodi::addon::Peripherals::FreeStructs(peripheral_count, scan_results);
+ }
- /*!
- * @brief Return the number of features belonging to the specified controller
- *
- * @param controllerId The controller ID to enumerate
- * @param type[optional] Type to filter by, or 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);
- }
+ 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;
- /*!
- * @brief Return the type of the feature
- *
- * @param controllerId The controller ID to check
- * @param featureName The feature to check
- *
- * @return The type of the specified feature, or JOYSTICK_FEATURE_TYPE_UNKNOWN
- * if unknown
- */
- JOYSTICK_FEATURE_TYPE FeatureType(const std::string& controllerId, const std::string &featureName)
+ std::vector<kodi::addon::PeripheralEvent> peripheralEvents;
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetEvents(peripheralEvents);
+ if (err == PERIPHERAL_NO_ERROR)
{
- return m_instanceData->toKodi.feature_type(m_instanceData->toKodi.kodiInstance, controllerId.c_str(), featureName.c_str());
+ *event_count = static_cast<unsigned int>(peripheralEvents.size());
+ kodi::addon::PeripheralEvents::ToStructs(peripheralEvents, events);
}
- private:
- void SetAddonStruct(KODI_HANDLE instance)
- {
- if (instance == nullptr)
- throw std::logic_error("kodi::addon::CInstancePeripheral: Creation with empty addon structure not allowed, table must be given from Kodi!");
-
- m_instanceData = static_cast<AddonInstance_Peripheral*>(instance);
- m_instanceData->toAddon.addonInstance = this;
-
- m_instanceData->toAddon.get_capabilities = ADDON_GetCapabilities;
- m_instanceData->toAddon.perform_device_scan = ADDON_PerformDeviceScan;
- m_instanceData->toAddon.free_scan_results = ADDON_FreeScanResults;
- m_instanceData->toAddon.get_events = ADDON_GetEvents;
- m_instanceData->toAddon.free_events = ADDON_FreeEvents;
- m_instanceData->toAddon.send_event = ADDON_SendEvent;
-
- m_instanceData->toAddon.get_joystick_info = ADDON_GetJoystickInfo;
- m_instanceData->toAddon.free_joystick_info = ADDON_FreeJoystickInfo;
- m_instanceData->toAddon.get_features = ADDON_GetFeatures;
- m_instanceData->toAddon.free_features = ADDON_FreeFeatures;
- m_instanceData->toAddon.map_features = ADDON_MapFeatures;
- m_instanceData->toAddon.get_ignored_primitives = ADDON_GetIgnoredPrimitives;
- m_instanceData->toAddon.free_primitives = ADDON_FreePrimitives;
- m_instanceData->toAddon.set_ignored_primitives = ADDON_SetIgnoredPrimitives;
- m_instanceData->toAddon.save_button_map = ADDON_SaveButtonMap;
- m_instanceData->toAddon.revert_button_map = ADDON_RevertButtonMap;
- m_instanceData->toAddon.reset_button_map = ADDON_ResetButtonMap;
- m_instanceData->toAddon.power_off_joystick = ADDON_PowerOffJoystick;
- }
+ return err;
+ }
- inline static void ADDON_GetCapabilities(const AddonInstance_Peripheral* addonInstance, PERIPHERAL_CAPABILITIES *capabilities)
- {
- addonInstance->toAddon.addonInstance->GetCapabilities(*capabilities);
- }
+ inline static void ADDON_FreeEvents(const AddonInstance_Peripheral* addonInstance,
+ unsigned int event_count,
+ PERIPHERAL_EVENT* events)
+ {
+ if (!addonInstance)
+ return;
- inline static PERIPHERAL_ERROR ADDON_PerformDeviceScan(const AddonInstance_Peripheral* addonInstance, unsigned int* peripheral_count, PERIPHERAL_INFO** scan_results)
- {
- return addonInstance->toAddon.addonInstance->PerformDeviceScan(peripheral_count, scan_results);
- }
+ kodi::addon::PeripheralEvents::FreeStructs(event_count, events);
+ }
- inline static void ADDON_FreeScanResults(const AddonInstance_Peripheral* addonInstance, unsigned int peripheral_count, PERIPHERAL_INFO* scan_results)
- {
- addonInstance->toAddon.addonInstance->FreeScanResults(peripheral_count, scan_results);
- }
+ 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_GetEvents(const AddonInstance_Peripheral* addonInstance, unsigned int* event_count, PERIPHERAL_EVENT** events)
- {
- return addonInstance->toAddon.addonInstance->GetEvents(event_count, events);
- }
- inline static void ADDON_FreeEvents(const AddonInstance_Peripheral* addonInstance, unsigned int event_count, PERIPHERAL_EVENT* events)
- {
- addonInstance->toAddon.addonInstance->FreeEvents(event_count, events);
- }
+ inline static PERIPHERAL_ERROR ADDON_GetJoystickInfo(
+ const AddonInstance_Peripheral* addonInstance, unsigned int index, JOYSTICK_INFO* info)
+ {
+ if (!addonInstance || !info)
+ return PERIPHERAL_ERROR_INVALID_PARAMETERS;
- inline static bool ADDON_SendEvent(const AddonInstance_Peripheral* addonInstance, const PERIPHERAL_EVENT* event)
+ kodi::addon::Joystick addonInfo;
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetJoystickInfo(index, addonInfo);
+ if (err == PERIPHERAL_NO_ERROR)
{
- return addonInstance->toAddon.addonInstance->SendEvent(event);
+ addonInfo.ToStruct(*info);
}
+ return err;
+ }
- inline static PERIPHERAL_ERROR ADDON_GetJoystickInfo(const AddonInstance_Peripheral* addonInstance, unsigned int index, JOYSTICK_INFO* info)
- {
- return addonInstance->toAddon.addonInstance->GetJoystickInfo(index, info);
- }
+ inline static void ADDON_FreeJoystickInfo(const AddonInstance_Peripheral* addonInstance,
+ JOYSTICK_INFO* info)
+ {
+ if (!addonInstance)
+ return;
- inline static void ADDON_FreeJoystickInfo(const AddonInstance_Peripheral* addonInstance, JOYSTICK_INFO* info)
- {
- addonInstance->toAddon.addonInstance->FreeJoystickInfo(info);
- }
+ 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)
- {
- return addonInstance->toAddon.addonInstance->GetFeatures(joystick, controller_id, feature_count, features);
- }
+ 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;
- inline static void ADDON_FreeFeatures(const AddonInstance_Peripheral* addonInstance, unsigned int feature_count, JOYSTICK_FEATURE* features)
- {
- addonInstance->toAddon.addonInstance->FreeFeatures(feature_count, features);
- }
+ kodi::addon::Joystick addonJoystick(*joystick);
+ std::vector<kodi::addon::JoystickFeature> featuresVector;
- 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)
+ PERIPHERAL_ERROR err = static_cast<CInstancePeripheral*>(addonInstance->toAddon->addonInstance)
+ ->GetFeatures(addonJoystick, controller_id, featuresVector);
+ if (err == PERIPHERAL_NO_ERROR)
{
- return addonInstance->toAddon.addonInstance->MapFeatures(joystick, controller_id, feature_count, features);
+ *feature_count = static_cast<unsigned int>(featuresVector.size());
+ kodi::addon::JoystickFeatures::ToStructs(featuresVector, features);
}
- inline static PERIPHERAL_ERROR ADDON_GetIgnoredPrimitives(const AddonInstance_Peripheral* addonInstance,
- const JOYSTICK_INFO* joystick, unsigned int* primitive_count,
- JOYSTICK_DRIVER_PRIMITIVE** primitives)
- {
- return addonInstance->toAddon.addonInstance->GetIgnoredPrimitives(joystick, primitive_count, primitives);
- }
+ return err;
+ }
- inline static void ADDON_FreePrimitives(const AddonInstance_Peripheral* addonInstance,
- unsigned int primitive_count, JOYSTICK_DRIVER_PRIMITIVE* primitives)
- {
- addonInstance->toAddon.addonInstance->FreePrimitives(primitive_count, primitives);
- }
+ inline static void ADDON_FreeFeatures(const AddonInstance_Peripheral* addonInstance,
+ unsigned int feature_count,
+ JOYSTICK_FEATURE* features)
+ {
+ if (!addonInstance)
+ return;
- inline static PERIPHERAL_ERROR ADDON_SetIgnoredPrimitives(const AddonInstance_Peripheral* addonInstance,
- const JOYSTICK_INFO* joystick, unsigned int primitive_count,
- const JOYSTICK_DRIVER_PRIMITIVE* primitives)
- {
- return addonInstance->toAddon.addonInstance->SetIgnoredPrimitives(joystick, primitive_count, primitives);
- }
+ kodi::addon::JoystickFeatures::FreeStructs(feature_count, features);
+ }
- inline static void ADDON_SaveButtonMap(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick)
- {
- addonInstance->toAddon.addonInstance->SaveButtonMap(joystick);
- }
+ 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;
- inline static void ADDON_RevertButtonMap(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick)
- {
- addonInstance->toAddon.addonInstance->RevertButtonMap(joystick);
- }
+ kodi::addon::Joystick addonJoystick(*joystick);
+ std::vector<kodi::addon::JoystickFeature> primitiveVector;
- inline static void ADDON_ResetButtonMap(const AddonInstance_Peripheral* addonInstance, const JOYSTICK_INFO* joystick, const char* controller_id)
- {
- addonInstance->toAddon.addonInstance->ResetButtonMap(joystick, controller_id);
- }
+ for (unsigned int i = 0; i < feature_count; i++)
+ primitiveVector.emplace_back(*(features + i));
- inline static void ADDON_PowerOffJoystick(const AddonInstance_Peripheral* addonInstance, unsigned int index)
+ 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)
{
- addonInstance->toAddon.addonInstance->PowerOffJoystick(index);
+ *primitive_count = static_cast<unsigned int>(primitiveVector.size());
+ kodi::addon::DriverPrimitives::ToStructs(primitiveVector, primitives);
}
- AddonInstance_Peripheral* m_instanceData;
- };
+ 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/PeripheralUtils.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
deleted file mode 100644
index 62e5a93026..0000000000
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * 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 "Peripheral.h"
-
-#include <array> // Requires c++11
-#include <cstring>
-#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
-{
- /*!
- * 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 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);
- }
- };
-
- /*!
- * ADDON::Peripheral
- *
- * Wrapper class providing peripheral information. Classes can extend
- * Peripheral to inherit peripheral properties.
- */
- class Peripheral
- {
- public:
- Peripheral(PERIPHERAL_TYPE type = PERIPHERAL_TYPE_UNKNOWN, const std::string& strName = "") :
- m_type(type),
- m_strName(strName)
- {
- }
-
- 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)
- {
- }
-
- virtual ~Peripheral(void) = default;
-
- PERIPHERAL_TYPE Type(void) const { return m_type; }
- const std::string& Name(void) const { return m_strName; }
- uint16_t VendorID(void) const { return m_vendorId; }
- uint16_t ProductID(void) const { return m_productId; }
- unsigned int Index(void) const { return m_index; }
-
- // Derived property: VID and PID are 0x0000 if unknown
- bool IsVidPidKnown(void) const { return m_vendorId != 0 || m_productId != 0; }
-
- void SetType(PERIPHERAL_TYPE type) { m_type = type; }
- void SetName(const std::string& strName) { m_strName = strName; }
- void SetVendorID(uint16_t vendorId) { m_vendorId = vendorId; }
- void SetProductID(uint16_t productId) { m_productId = productId; }
- void SetIndex(unsigned int index) { m_index = 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;
-
- /*!
- * ADDON::PeripheralEvent
- *
- * Wrapper class for peripheral events.
- */
- class PeripheralEvent
- {
- public:
- PeripheralEvent() = default;
-
- 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)
- {
- }
-
- 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)
- {
- }
-
- 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)
- {
- }
-
- 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)
- {
- }
-
- PERIPHERAL_EVENT_TYPE Type(void) const { return m_type; }
- unsigned int PeripheralIndex(void) const { return m_peripheralIndex; }
- unsigned int DriverIndex(void) const { return m_driverIndex; }
- JOYSTICK_STATE_BUTTON ButtonState(void) const { return m_buttonState; }
- JOYSTICK_STATE_HAT HatState(void) const { return m_hatState; }
- JOYSTICK_STATE_AXIS AxisState(void) const { return m_axisState; }
- JOYSTICK_STATE_MOTOR MotorState(void) const { return m_motorState; }
-
- void SetType(PERIPHERAL_EVENT_TYPE type) { m_type = type; }
- void SetPeripheralIndex(unsigned int index) { m_peripheralIndex = index; }
- void SetDriverIndex(unsigned int index) { m_driverIndex = index; }
- void SetButtonState(JOYSTICK_STATE_BUTTON state) { m_buttonState = state; }
- void SetHatState(JOYSTICK_STATE_HAT state) { m_hatState = state; }
- void SetAxisState(JOYSTICK_STATE_AXIS state) { m_axisState = state; }
- void SetMotorState(JOYSTICK_STATE_MOTOR state) { m_motorState = 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;
-
- /*!
- * kodi::addon::Joystick
- *
- * Wrapper class providing additional joystick information not provided by
- * ADDON::Peripheral.
- */
- class Joystick : public Peripheral
- {
- public:
- Joystick(const std::string& provider = "", const std::string& strName = "") :
- Peripheral(PERIPHERAL_TYPE_JOYSTICK, strName),
- m_provider(provider),
- m_requestedPort(NO_PORT_REQUESTED)
- {
- }
-
- Joystick(const Joystick& other)
- {
- *this = other;
- }
-
- 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)
- {
- }
-
- ~Joystick(void) override = default;
-
- 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;
- }
-
- const std::string& Provider(void) const { return m_provider; }
- int RequestedPort(void) const { return m_requestedPort; }
- unsigned int ButtonCount(void) const { return m_buttonCount; }
- unsigned int HatCount(void) const { return m_hatCount; }
- unsigned int AxisCount(void) const { return m_axisCount; }
- unsigned int MotorCount(void) const { return m_motorCount; }
- bool SupportsPowerOff(void) const { return m_supportsPowerOff; }
-
- void SetProvider(const std::string& provider) { m_provider = provider; }
- void SetRequestedPort(int requestedPort) { m_requestedPort = requestedPort; }
- void SetButtonCount(unsigned int buttonCount) { m_buttonCount = buttonCount; }
- void SetHatCount(unsigned int hatCount) { m_hatCount = hatCount; }
- void SetAxisCount(unsigned int axisCount) { m_axisCount = axisCount; }
- void SetMotorCount(unsigned int motorCount) { m_motorCount = motorCount; }
- void SetSupportsPowerOff(bool supportsPowerOff) { m_supportsPowerOff = supportsPowerOff; }
-
- 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;
-
- /*!
- * ADDON::DriverPrimitive
- *
- * 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:
- /*!
- * \brief Construct an invalid driver primitive
- */
- DriverPrimitive(void) = default;
-
- /*!
- * \brief Construct a driver primitive representing a joystick button
- */
- 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
- */
- 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
- */
- 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
- */
- 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
- */
- 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
- */
- 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
- */
- DriverPrimitive(JOYSTICK_DRIVER_RELPOINTER_DIRECTION direction) :
- m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION),
- m_relPointerDirection(direction)
- {
- }
-
- 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;
- }
- }
-
- JOYSTICK_DRIVER_PRIMITIVE_TYPE Type(void) const { return m_type; }
- unsigned int DriverIndex(void) const { return m_driverIndex; }
- JOYSTICK_DRIVER_HAT_DIRECTION HatDirection(void) const { return m_hatDirection; }
- int Center(void) const { return m_center; }
- JOYSTICK_DRIVER_SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; }
- unsigned int Range(void) const { return m_range; }
- const std::string& Keycode(void) const { return m_keycode; }
- JOYSTICK_DRIVER_MOUSE_INDEX MouseIndex(void) const { return static_cast<JOYSTICK_DRIVER_MOUSE_INDEX>(m_driverIndex); }
- JOYSTICK_DRIVER_RELPOINTER_DIRECTION RelPointerDirection(void) const { return m_relPointerDirection; }
-
- 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;
- }
-
- 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;
-
- /*!
- * kodi::addon::JoystickFeature
- *
- * 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:
- JoystickFeature(const std::string& name = "", JOYSTICK_FEATURE_TYPE type = JOYSTICK_FEATURE_TYPE_UNKNOWN) :
- m_name(name),
- m_type(type),
- m_primitives{}
- {
- }
-
- JoystickFeature(const JoystickFeature& other)
- {
- *this = other;
- }
-
- 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]);
- }
-
- 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;
- }
-
- bool operator==(const JoystickFeature& other) const
- {
- return m_name == other.m_name &&
- m_type == other.m_type &&
- m_primitives == other.m_primitives;
- }
-
- const std::string& Name(void) const { return m_name; }
- JOYSTICK_FEATURE_TYPE Type(void) const { return m_type; }
- bool IsValid() const { return m_type != JOYSTICK_FEATURE_TYPE_UNKNOWN; }
-
- void SetName(const std::string& name) { m_name = name; }
- void SetType(JOYSTICK_FEATURE_TYPE type) { m_type = type; }
- void SetInvalid(void) { m_type = JOYSTICK_FEATURE_TYPE_UNKNOWN; }
-
- const DriverPrimitive& Primitive(JOYSTICK_FEATURE_PRIMITIVE which) const { return m_primitives[which]; }
- void SetPrimitive(JOYSTICK_FEATURE_PRIMITIVE which, const DriverPrimitive& primitive) { m_primitives[which] = primitive; }
-
- std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX>& Primitives() { return m_primitives; }
- const std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX>& Primitives() const { return m_primitives; }
-
- 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 */
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
index efd5de25d3..177bf7269e 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h
@@ -9,260 +9,146 @@
#include "../AddonBase.h"
#include "../Filesystem.h"
-
-#if !defined(_WIN32)
-#include <sys/stat.h>
-#if !defined(__stat64)
-#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD)
-#define __stat64 stat
-#else
-#define __stat64 stat64
-#endif
-#endif
-#endif
+#include "../c-api/addon-instance/vfs.h"
#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
- //============================================================================
- /// @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.
- ///
- struct 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>
- const char* url;
-
- /// @brief The associated domain name, which is optional and not available
- /// in all cases.
- const char* 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`).
- const char* hostname;
-
- /// @brief With this variable the desired path to a folder or file within
- /// the hostname is given (e.g. `storage/videos/00001.ts`).
- const char* filename;
-
- /// @brief [Networking port](https://en.wikipedia.org/wiki/Port_(computer_networking))
- /// to use for protocol.
- unsigned int 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.
- const char* options;
-
- /// @brief Desired username.
- const char* username;
- /// @brief Desired password.
- const char* 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>.
- const char* 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.
- const char* sharename;
+namespace kodi
+{
+namespace addon
+{
- /// @brief Protocol name used on this stream, e.g. <b>`sftp`</b>.
- const char* protocol;
- };
- //----------------------------------------------------------------------------
+class CInstanceVFS;
- //============================================================================
- /// @ingroup cpp_kodi_addon_vfs_Defs
- /// @brief <b>In/out value which is queried at @ref kodi::addon::CInstanceVFS::IoControl.</b>\n
- /// This declares the requested value on the addon, this gets or has to
- /// transfer data depending on the value.
- enum VFS_IOCTRL
- {
- /// @brief For cases where not supported control becomes asked.
- ///
- /// @note Should normally not given to addon.
- VFS_IOCTRL_INVALID = 0,
+//==============================================================================
+/// @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;
+///@}
+//------------------------------------------------------------------------------
- /// @brief @ref VFS_IOCTRL_NATIVE_DATA structure, containing what should be
- /// passed to native ioctrl.
- VFS_IOCTRL_NATIVE = 1,
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN VFSUrl : public CStructHdl<VFSUrl, VFSURL>
+{
+ /*! \cond PRIVATE */
+ friend class CInstanceVFS;
+ /*! \endcond */
- /// @brief To check seek is possible.
- ///
- //// Return 0 if known not to work, 1 if it should work on related calls.
- VFS_IOCTRL_SEEK_POSSIBLE = 2,
+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"
+ ///
- /// @brief @ref VFS_IOCTRL_CACHE_STATUS_DATA structure structure on related call
- VFS_IOCTRL_CACHE_STATUS = 3,
+ /// @addtogroup cpp_kodi_addon_vfs_Defs_VFSUrl
+ ///@{
- /// @brief Unsigned int with speed limit for caching in bytes per second
- VFS_IOCTRL_CACHE_SETRATE = 4,
+ /// @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 Enable/disable retry within the protocol handler (if supported)
- VFS_IOCTRL_SET_RETRY = 16,
- };
- //----------------------------------------------------------------------------
+ /// @brief The associated domain name, which is optional and not available
+ /// in all cases.
+ std::string GetDomain() const { return m_cStructure->domain; }
- //============================================================================
- /// @ingroup cpp_kodi_addon_vfs_Defs
- /// @brief <b>Structure used in @ref kodi::addon::CInstanceVFS::IoControl
- /// if question value for @ref VFS_IOCTRL_NATIVE is set</b>\n
- /// With this structure, data is transmitted to the Kodi addon.
- ///
- /// This corresponds to POSIX systems with regard to [ioctl](https://en.wikipedia.org/wiki/Ioctl)
- /// data (emulated with Windows).
- struct VFS_IOCTRL_NATIVE_DATA
- {
- unsigned long int request;
- void* param;
- };
- //----------------------------------------------------------------------------
+ /// @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; }
- //============================================================================
- /// @ingroup cpp_kodi_addon_vfs_Defs
- /// @brief <b>Structure used in @ref kodi::addon::CInstanceVFS::IoControl
- /// if question value for @ref VFS_IOCTRL_CACHE_STATUS is set</b>\n
- /// This data is filled by the addon and returned to Kodi
- struct VFS_IOCTRL_CACHE_STATUS_DATA
- {
- /// @brief Number of bytes cached forward of current position.
- uint64_t forward;
+ /// @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 Maximum number of bytes per second cache is allowed to fill.
- unsigned int maxrate;
+ /// @brief [Networking port](https://en.wikipedia.org/wiki/Port_(computer_networking))
+ /// to use for protocol.
+ unsigned int GetPort() const { return m_cStructure->port; }
- /// @brief Average read rate from source file since last position change.
- unsigned int currate;
+ /// @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 Cache low speed condition detected?
- bool lowspeed;
- };
- //----------------------------------------------------------------------------
+ /// @brief Desired username.
+ std::string GetUsername() const { return m_cStructure->username; }
- typedef struct VFSGetDirectoryCallbacks /* internal */
- {
- bool (__cdecl* get_keyboard_input)(void* ctx, const char* heading, char** input, bool hidden_input);
- void (__cdecl* set_error_dialog)(void* ctx, const char* heading, const char* line1, const char* line2, const char* line3);
- void (__cdecl* require_authentication)(void* ctx, const char* url);
- void* ctx;
- } VFSGetDirectoryCallbacks;
+ /// @brief Desired password.
+ std::string GetPassword() const { return m_cStructure->password; }
- typedef struct AddonProps_VFSEntry /* internal */
- {
- int dummy;
- } AddonProps_VFSEntry;
+ /// @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; }
- typedef struct AddonToKodiFuncTable_VFSEntry /* internal */
- {
- KODI_HANDLE kodiInstance;
- } AddonToKodiFuncTable_VFSEntry;
+ /// @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; }
- struct AddonInstance_VFSEntry;
- typedef struct KodiToAddonFuncTable_VFSEntry /* internal */
- {
- KODI_HANDLE addonInstance;
-
- void*(__cdecl* open)(const struct AddonInstance_VFSEntry* instance, const struct VFSURL* url);
- void*(__cdecl* open_for_write)(const struct AddonInstance_VFSEntry* instance,
- const struct VFSURL* url,
- bool overwrite);
- ssize_t(__cdecl* read)(const struct AddonInstance_VFSEntry* instance,
- void* context,
- void* buffer,
- size_t buf_size);
- ssize_t(__cdecl* write)(const struct AddonInstance_VFSEntry* instance,
- void* context,
- const void* buffer,
- size_t buf_size);
- int64_t(__cdecl* seek)(const struct AddonInstance_VFSEntry* instance,
- void* context,
- int64_t position,
- int whence);
- int(__cdecl* truncate)(const struct AddonInstance_VFSEntry* instance,
- void* context,
- int64_t size);
- int64_t(__cdecl* get_length)(const struct AddonInstance_VFSEntry* instance, void* context);
- int64_t(__cdecl* get_position)(const struct AddonInstance_VFSEntry* instance, void* context);
- int(__cdecl* get_chunk_size)(const struct AddonInstance_VFSEntry* instance, void* context);
- int(__cdecl* io_control)(const struct AddonInstance_VFSEntry* instance,
- void* context,
- enum VFS_IOCTRL request,
- void* param);
- int(__cdecl* stat)(const struct AddonInstance_VFSEntry* instance,
- const struct VFSURL* url,
- struct __stat64* buffer);
- bool(__cdecl* close)(const struct AddonInstance_VFSEntry* instance, void* 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,
- 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 */
- {
- AddonProps_VFSEntry* props;
- AddonToKodiFuncTable_VFSEntry* toKodi;
- KodiToAddonFuncTable_VFSEntry* toAddon;
- } AddonInstance_VFSEntry;
+ /// @brief Protocol name used on this stream, e.g. <b>`sftp`</b>.
+ std::string GetProtocol() const { return m_cStructure->protocol; }
-#ifdef __cplusplus
-} /* extern "C" */
+ ///@}
-namespace kodi
-{
-namespace addon
-{
+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
@@ -499,14 +385,14 @@ namespace addon
/// };
///
/// CMyVFS::CMyVFS(KODI_HANDLE instance, const std::string& kodiVersion)
-/// : CInstanceVFS(instance, kodiVersion)
+/// : kodi::addon::CInstanceVFS(instance, kodiVersion)
/// {
/// ...
/// }
///
/// ...
///
-/// /*----------------------------------------------------------------------*/
+/// //----------------------------------------------------------------------
///
/// class CMyAddon : public kodi::addon::CAddonBase
/// {
@@ -529,7 +415,7 @@ namespace addon
/// {
/// if (instanceType == ADDON_INSTANCE_VFS)
/// {
-/// kodi::Log(ADDON_LOG_NOTICE, "Creating my VFS instance");
+/// kodi::Log(ADDON_LOG_INFO, "Creating my VFS instance");
/// addonInstance = new CMyVFS(instance, version);
/// return ADDON_STATUS_OK;
/// }
@@ -546,12 +432,11 @@ namespace addon
/// The destruction of the example class `CMyVFS` is called from
/// Kodi's header. Manually deleting the add-on instance is not required.
///
-//----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
class ATTRIBUTE_HIDDEN CInstanceVFS : public IAddonInstance
{
public:
- //==========================================================================
- ///
+ //============================================================================
/// @ingroup cpp_kodi_addon_vfs
/// @brief VFS class constructor used to support multiple instance
/// types
@@ -577,18 +462,16 @@ public:
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**
@@ -597,8 +480,7 @@ public:
/// locations and file system queries.
///
- //==========================================================================
- ///
+ //============================================================================
/// @defgroup cpp_kodi_addon_vfs_filecontrol 2. File editing functions
/// @ingroup cpp_kodi_addon_vfs
/// @brief **File editing functions.**
@@ -608,17 +490,22 @@ public:
///
//@{
- //==========================================================================
- ///
+ //============================================================================
/// @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
- virtual void* Open(const VFSURL& url) { return nullptr; }
-
- //==========================================================================
///
+ ///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @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
///
@@ -626,22 +513,23 @@ public:
/// @param[in] overWrite Whether or not to overwrite an existing file
/// @return Context for the opened file
///
- virtual void* OpenForWrite(const VFSURL& url, bool overWrite) { return nullptr; }
- //--------------------------------------------------------------------------
+ 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(void* context) { return false; }
- //--------------------------------------------------------------------------
+ virtual bool Close(kodi::addon::VFSFileHandle context) { return false; }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
+ //============================================================================
/// @ingroup cpp_kodi_addon_vfs_filecontrol
/// @brief Read from a file
///
@@ -650,11 +538,13 @@ public:
/// @param[in] uiBufSize Number of bytes to read
/// @return Number of bytes read
///
- virtual ssize_t Read(void* context, void* buffer, size_t uiBufSize) { return -1; }
- //--------------------------------------------------------------------------
+ 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
///
@@ -663,24 +553,33 @@ public:
/// @param[in] uiBufSize Number of bytes to write
/// @return Number of bytes written
///
- virtual ssize_t Write(void* context, const void* buffer, size_t uiBufSize) { return -1; }
- //--------------------------------------------------------------------------
+ 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)
+ /// @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(void* context, int64_t position, int whence) { return -1; }
- //--------------------------------------------------------------------------
+ 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
///
@@ -688,59 +587,91 @@ public:
/// @param[in] size The size to truncate the file to
/// @return 0 on success, -1 on error
///
- virtual int Truncate(void* context, int64_t size) { return -1; }
- //--------------------------------------------------------------------------
+ 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(void* context) { return 0; }
- //--------------------------------------------------------------------------
+ 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(void* context) { return 0; }
- //--------------------------------------------------------------------------
+ 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(void* context) { return 1; }
- //--------------------------------------------------------------------------
+ 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 Perform an IO-control on the file
+ /// @brief To check a running stream on file for state of his cache.
+ ///
+ /// @param[in] status Information about current cache status
+ /// @return true if successfull done, false otherwise
///
- /// @param[in] context The context of the file
- /// @param[in] request The requested IO-control
- /// @param[in] param Parameter attached to the IO-control
- /// @return -1 on error, >= 0 on success
///
- virtual int IoControl(void* context, VFS_IOCTRL request, void* param) { return -1; }
- //--------------------------------------------------------------------------
+ /// @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 successfull done, false otherwise
+ ///
+ virtual bool IoControlSetCacheRate(kodi::addon::VFSFileHandle context, unsigned int 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 successfull done, false otherwise
+ ///
+ virtual bool IoControlSetRetry(kodi::addon::VFSFileHandle context, bool retry) { return false; }
+ //----------------------------------------------------------------------------
//@}
//@{
- //==========================================================================
- ///
+ //============================================================================
/// @ingroup cpp_kodi_addon_vfs_general
/// @brief Stat a file
///
@@ -748,49 +679,49 @@ public:
/// @param[in] buffer The buffer to store results in
/// @return -1 on error, 0 otherwise
///
- virtual int Stat(const VFSURL& url, struct __stat64* buffer) { return 0; }
- //--------------------------------------------------------------------------
-
- //==========================================================================
///
+ /// ----------------------------------------------------------------------------
+ ///
+ /// @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 VFSURL& url) { return false; }
- //--------------------------------------------------------------------------
+ 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 VFSURL& url) { return false; }
- //--------------------------------------------------------------------------
+ virtual bool Delete(const kodi::addon::VFSUrl& url) { return false; }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
+ //============================================================================
/// @ingroup cpp_kodi_addon_vfs_general
/// @brief Rename a file
///
@@ -798,45 +729,44 @@ public:
/// @param[in] url2 The URL of the destination file
/// @return True if deletion was successful, false otherwise
///
- virtual bool Rename(const VFSURL& url, const VFSURL& url2) { return false; }
- //--------------------------------------------------------------------------
+ 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 VFSURL& url) { return false; }
- //--------------------------------------------------------------------------
+ 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 VFSURL& url) { return false; }
- //--------------------------------------------------------------------------
+ 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 VFSURL& url) { return false; }
- //--------------------------------------------------------------------------
+ virtual bool CreateDirectory(const kodi::addon::VFSUrl& url) { return false; }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// @defgroup cpp_kodi_addon_vfs_general_cb_GetDirectory **Callbacks GetDirectory()**
+ //============================================================================
+ /// @defgroup cpp_kodi_addon_vfs_general_cb_GetDirectory Callbacks GetDirectory()
/// @ingroup cpp_kodi_addon_vfs_general
/// @brief Callback functions on GetDirectory()
///
@@ -853,7 +783,9 @@ public:
///
/// ...
///
- /// bool CMyVFS::GetDirectory(const VFSURL& url, std::vector<kodi::vfs::CDirEntry>& items, CVFSCallbacks callbacks)
+ /// bool CMyVFS::GetDirectory(const kodi::addon::VFSUrl& url,
+ /// std::vector<kodi::vfs::CDirEntry>& items,
+ /// CVFSCallbacks callbacks)
/// {
/// std::string neededString;
/// callbacks.GetKeyboardInput("Test", neededString, true);
@@ -925,10 +857,9 @@ public:
private:
const VFSGetDirectoryCallbacks* m_cb;
};
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
+ //============================================================================
/// @ingroup cpp_kodi_addon_vfs_general
/// @brief List a directory
///
@@ -952,16 +883,15 @@ public:
/// | CVFSCallbacks::SetErrorDialog | @copybrief CVFSCallbacks::SetErrorDialog @copydetails CVFSCallbacks::SetErrorDialog
/// | CVFSCallbacks::RequireAuthentication | @copybrief CVFSCallbacks::RequireAuthentication @copydetails CVFSCallbacks::RequireAuthentication
///
- virtual bool GetDirectory(const VFSURL& url,
+ 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)
///
@@ -972,13 +902,13 @@ public:
/// @param[out] rootPath Path to root directory if multiple entries
/// @return Context for the directory listing
///
- virtual bool ContainsFiles(const VFSURL& url,
+ virtual bool ContainsFiles(const kodi::addon::VFSUrl& url,
std::vector<kodi::vfs::CDirEntry>& entries,
std::string& rootPath)
{
return false;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
//@}
private:
@@ -999,7 +929,10 @@ private:
m_instanceData->toAddon->get_length = ADDON_GetLength;
m_instanceData->toAddon->get_position = ADDON_GetPosition;
m_instanceData->toAddon->get_chunk_size = ADDON_GetChunkSize;
- m_instanceData->toAddon->io_control = ADDON_IoControl;
+ m_instanceData->toAddon->io_control_get_seek_possible = ADDON_IoControlGetSeekPossible;
+ m_instanceData->toAddon->io_control_get_cache_status = ADDON_IoControlGetCacheStatus;
+ m_instanceData->toAddon->io_control_set_cache_rate = ADDON_IoControlSetCacheRate;
+ m_instanceData->toAddon->io_control_set_retry = ADDON_IoControlSetRetry;
m_instanceData->toAddon->stat = ADDON_Stat;
m_instanceData->toAddon->close = ADDON_Close;
m_instanceData->toAddon->exists = ADDON_Exists;
@@ -1015,22 +948,23 @@ private:
m_instanceData->toAddon->contains_files = ADDON_ContainsFiles;
}
- inline static void* ADDON_Open(const AddonInstance_VFSEntry* instance, const VFSURL* url)
+ inline static VFS_FILE_HANDLE ADDON_Open(const AddonInstance_VFSEntry* instance,
+ const VFSURL* url)
{
- return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Open(*url);
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Open(url);
}
- inline static void* ADDON_OpenForWrite(const AddonInstance_VFSEntry* instance,
- const VFSURL* url,
- bool overWrite)
+ 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);
+ ->OpenForWrite(url, overWrite);
}
inline static ssize_t ADDON_Read(const AddonInstance_VFSEntry* instance,
- void* context,
- void* buffer,
+ VFS_FILE_HANDLE context,
+ uint8_t* buffer,
size_t uiBufSize)
{
return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
@@ -1038,8 +972,8 @@ private:
}
inline static ssize_t ADDON_Write(const AddonInstance_VFSEntry* instance,
- void* context,
- const void* buffer,
+ VFS_FILE_HANDLE context,
+ const uint8_t* buffer,
size_t uiBufSize)
{
return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
@@ -1047,7 +981,7 @@ private:
}
inline static int64_t ADDON_Seek(const AddonInstance_VFSEntry* instance,
- void* context,
+ VFS_FILE_HANDLE context,
int64_t position,
int whence)
{
@@ -1056,51 +990,78 @@ private:
}
inline static int ADDON_Truncate(const AddonInstance_VFSEntry* instance,
- void* context,
+ 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, void* context)
+ 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, void* 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, void* 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 int ADDON_IoControl(const AddonInstance_VFSEntry* instance,
- void* context,
- enum VFS_IOCTRL request,
- void* param)
+ 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,
+ unsigned int 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)
- ->IoControl(context, request, param);
+ ->IoControlSetRetry(context, retry);
}
inline static int ADDON_Stat(const AddonInstance_VFSEntry* instance,
const VFSURL* url,
- struct __stat64* buffer)
+ struct STAT_STRUCTURE* buffer)
{
- return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Stat(*url, 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, void* context)
+ 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);
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Exists(url);
}
inline static void ADDON_ClearOutIdle(const AddonInstance_VFSEntry* instance)
@@ -1115,32 +1076,32 @@ private:
inline static bool ADDON_Delete(const AddonInstance_VFSEntry* instance, const VFSURL* url)
{
- return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->Delete(*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);
+ 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);
+ 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);
+ 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);
+ return static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)->CreateDirectory(url);
}
inline static bool ADDON_GetDirectory(const AddonInstance_VFSEntry* instance,
@@ -1151,7 +1112,7 @@ private:
{
std::vector<kodi::vfs::CDirEntry> addonEntries;
bool ret = static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
- ->GetDirectory(*url, addonEntries, CVFSCallbacks(callbacks));
+ ->GetDirectory(url, addonEntries, CVFSCallbacks(callbacks));
if (ret)
{
VFSDirEntry* entries =
@@ -1218,7 +1179,7 @@ private:
std::string cppRootPath;
std::vector<kodi::vfs::CDirEntry> addonEntries;
bool ret = static_cast<CInstanceVFS*>(instance->toAddon->addonInstance)
- ->ContainsFiles(*url, addonEntries, cppRootPath);
+ ->ContainsFiles(url, addonEntries, cppRootPath);
if (ret)
{
strncpy(rootpath, cppRootPath.c_str(), ADDON_STANDARD_STRING_LENGTH);
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
index 1ae2353dcf..7b1db6503e 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Visualization.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Visualization.h
@@ -375,7 +375,7 @@ private:
/// {
/// if (instanceType == ADDON_INSTANCE_VISUALIZATION)
/// {
-/// kodi::Log(ADDON_LOG_NOTICE, "Creating my visualization");
+/// kodi::Log(ADDON_LOG_INFO, "Creating my visualization");
/// addonInstance = new CMyVisualization(instance, version);
/// return ADDON_STATUS_OK;
/// }
@@ -449,7 +449,7 @@ public:
/// const std::string& version,
/// KODI_HANDLE& addonInstance)
/// {
- /// kodi::Log(ADDON_LOG_NOTICE, "Creating my visualization");
+ /// kodi::Log(ADDON_LOG_INFO, "Creating my visualization");
/// addonInstance = new CMyVisualization(instance, version);
/// return ADDON_STATUS_OK;
/// }
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 0000000000..d6fba6965a
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(HEADERS PeripheralUtils.h)
+
+if(NOT ENABLE_STATIC_LIBS)
+ core_add_library(addons_kodi-dev-kit_include_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 0000000000..febaeb9585
--- /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) { *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/c-api/CMakeLists.txt b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/CMakeLists.txt
index 5db93daa01..091e0fe5b8 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/CMakeLists.txt
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/CMakeLists.txt
@@ -4,6 +4,10 @@ set(HEADERS addon_base.h
general.h
network.h)
+if(CORE_SYSTEM_NAME STREQUAL android)
+ list(APPEND SOURCES platform/android/system.h)
+endif()
+
if(NOT ENABLE_STATIC_LIBS)
core_add_library(addons_kodi-dev-kit_include_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
index 96c57d2f60..4edd034ebf 100644
--- 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
@@ -1,8 +1,11 @@
set(HEADERS audio_decoder.h
audio_encoder.h
+ game.h
image_decoder.h
+ peripheral.h
pvr.h
screensaver.h
+ vfs.h
visualization.h)
if(NOT ENABLE_STATIC_LIBS)
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 0000000000..c97fa5d3aa
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/game.h
@@ -0,0 +1,1212 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#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;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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 to used 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;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_PACKED game_stream_hw_framebuffer_properties;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Hardware framebuffer buffer**
+ ///
+ typedef struct game_stream_hw_framebuffer_buffer
+ {
+ /// @brief
+ uintptr_t framebuffer;
+ } ATTRIBUTE_PACKED game_stream_hw_framebuffer_buffer;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief **Hardware framebuffer packet**
+ ///
+ typedef struct game_stream_hw_framebuffer_packet
+ {
+ /// @brief
+ uintptr_t framebuffer;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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;
+ };
+ } ATTRIBUTE_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;
+ };
+ } ATTRIBUTE_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;
+ };
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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
+ game_input_device* accepted_devices;
+
+ /// @brief
+ unsigned int device_count;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_PACKED game_input_topology;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_digital_button_event
+ {
+ /// @brief
+ bool pressed;
+ } ATTRIBUTE_PACKED game_digital_button_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_analog_button_event
+ {
+ /// @brief
+ float magnitude;
+ } ATTRIBUTE_PACKED game_analog_button_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_axis_event
+ {
+ /// @brief
+ float position;
+ } ATTRIBUTE_PACKED game_axis_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_analog_stick_event
+ {
+ /// @brief
+ float x;
+
+ /// @brief
+ float y;
+ } ATTRIBUTE_PACKED game_analog_stick_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_accelerometer_event
+ {
+ /// @brief
+ float x;
+
+ /// @brief
+ float y;
+
+ /// @brief
+ float z;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_PACKED game_key_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_rel_pointer_event
+ {
+ /// @brief
+ int x;
+
+ /// @brief
+ int y;
+ } ATTRIBUTE_PACKED game_rel_pointer_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_abs_pointer_event
+ {
+ /// @brief
+ bool pressed;
+
+ /// @brief
+ float x;
+
+ /// @brief
+ float y;
+ } ATTRIBUTE_PACKED game_abs_pointer_event;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief
+ typedef struct game_motor_event
+ {
+ /// @brief
+ float magnitude;
+ } ATTRIBUTE_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;
+ };
+ } ATTRIBUTE_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*);
+ } 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/peripheral.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/peripheral.h
new file mode 100644
index 0000000000..393f34a0c6
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/peripheral.h
@@ -0,0 +1,709 @@
+/*
+ * 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
+
+#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 */
+ } ATTRIBUTE_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 */
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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 */
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_PACKED JOYSTICK_DRIVER_SEMIAXIS;
+
+ /*!
+ * @brief Motor primitive
+ */
+ typedef struct JOYSTICK_DRIVER_MOTOR
+ {
+ int index;
+ } ATTRIBUTE_PACKED JOYSTICK_DRIVER_MOTOR;
+
+ /*!
+ * @brief Keyboard key primitive
+ */
+ typedef struct JOYSTICK_DRIVER_KEY
+ {
+ char keycode[16];
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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;
+ } ATTRIBUTE_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;
+ };
+ } ATTRIBUTE_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 absolut 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];
+ } ATTRIBUTE_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 */
+ } ATTRIBUTE_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/pvr_general.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_general.h
index 7bfb997059..e2136f6bb3 100644
--- 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
@@ -210,7 +210,7 @@ extern "C"
/// {
/// if (instanceType == ADDON_INSTANCE_INPUTSTREAM)
/// {
- /// kodi::Log(ADDON_LOG_NOTICE, "Creating my special 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")
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 0000000000..a6c3f44b63
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/vfs.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#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,
+ VFS_CACHE_STATUS_DATA* status);
+ bool(__cdecl* io_control_set_cache_rate)(const struct AddonInstance_VFSEntry* instance,
+ VFS_FILE_HANDLE context,
+ unsigned int 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/filesystem.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h
index 14fdbc75b0..70f9400ebb 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/filesystem.h
@@ -28,6 +28,9 @@ typedef intptr_t ssize_t;
#ifdef DeleteFile
#undef DeleteFile
#endif // DeleteFile
+#ifdef RemoveDirectory
+#undef RemoveDirectory
+#endif // RemoveDirectory
#endif // _WIN32
#ifdef TARGET_POSIX // Linux, Mac, FreeBSD
@@ -201,6 +204,19 @@ extern "C"
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
@@ -297,6 +313,7 @@ extern "C"
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;
//}}}
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 0000000000..53c4e60aeb
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(HEADERS definitions.h
+ general.h
+ list_item.h
+ window.h)
+
+if(NOT ENABLE_STATIC_LIBS)
+ core_add_library(addons_kodi-dev-kit_include_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 0000000000..2e6cd53f89
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/CMakeLists.txt
@@ -0,0 +1,16 @@
+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(NOT ENABLE_STATIC_LIBS)
+ core_add_library(addons_kodi-dev-kit_include_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 0000000000..84fd8227d1
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/button.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.
+ */
+
+#pragma once
+
+#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 0000000000..ca38b273fc
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/edit.h
@@ -0,0 +1,79 @@
+/*
+ * 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
+
+#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 0000000000..fea014b623
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/fade_label.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.
+ */
+
+#pragma once
+
+#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 0000000000..4a46e6da5b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/image.h
@@ -0,0 +1,37 @@
+/*
+ * 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
+
+#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 0000000000..d8a9fe4a58
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/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.
+ */
+
+#pragma once
+
+#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 0000000000..88638e0859
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/progress.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.
+ */
+
+#pragma once
+
+#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 0000000000..a672d9516a
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/radio_button.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.
+ */
+
+#pragma once
+
+#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 0000000000..d4053a6411
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/rendering.h
@@ -0,0 +1,38 @@
+/*
+ * 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
+
+#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 0000000000..2cbc972bdd
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/settings_slider.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.
+ */
+
+#pragma once
+
+#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 0000000000..0a67208c7b
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/slider.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.
+ */
+
+#pragma once
+
+#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 0000000000..d5e5c861a3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/spin.h
@@ -0,0 +1,58 @@
+/*
+ * 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
+
+#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 0000000000..276d04cb28
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/controls/text_box.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.
+ */
+
+#pragma once
+
+#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 0000000000..ec60bc2843
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/definitions.h
@@ -0,0 +1,106 @@
+/*
+ * 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
+
+#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;
+
+ struct AddonToKodiFuncTable_kodi_gui_general;
+ struct AddonToKodiFuncTable_kodi_gui_control_button;
+ struct AddonToKodiFuncTable_kodi_gui_control_edit;
+ struct AddonToKodiFuncTable_kodi_gui_control_fade_label;
+ struct AddonToKodiFuncTable_kodi_gui_control_label;
+ struct AddonToKodiFuncTable_kodi_gui_control_image;
+ struct AddonToKodiFuncTable_kodi_gui_control_progress;
+ struct AddonToKodiFuncTable_kodi_gui_control_radio_button;
+ struct AddonToKodiFuncTable_kodi_gui_control_rendering;
+ struct AddonToKodiFuncTable_kodi_gui_control_settings_slider;
+ struct AddonToKodiFuncTable_kodi_gui_control_slider;
+ struct AddonToKodiFuncTable_kodi_gui_control_spin;
+ struct AddonToKodiFuncTable_kodi_gui_control_text_box;
+ struct AddonToKodiFuncTable_kodi_gui_dialogContextMenu;
+ struct AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress;
+ struct AddonToKodiFuncTable_kodi_gui_dialogFileBrowser;
+ struct AddonToKodiFuncTable_kodi_gui_dialogKeyboard;
+ struct AddonToKodiFuncTable_kodi_gui_dialogNumeric;
+ struct AddonToKodiFuncTable_kodi_gui_dialogOK;
+ struct AddonToKodiFuncTable_kodi_gui_dialogProgress;
+ struct AddonToKodiFuncTable_kodi_gui_dialogSelect;
+ struct AddonToKodiFuncTable_kodi_gui_dialogTextViewer;
+ struct AddonToKodiFuncTable_kodi_gui_dialogYesNo;
+ struct AddonToKodiFuncTable_kodi_gui_listItem;
+ struct AddonToKodiFuncTable_kodi_gui_window;
+
+ 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 0000000000..bc35e91604
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/CMakeLists.txt
@@ -0,0 +1,14 @@
+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(NOT ENABLE_STATIC_LIBS)
+ core_add_library(addons_kodi-dev-kit_include_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 0000000000..8bb5370c28
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/context_menu.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.
+ */
+
+#pragma once
+
+#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 0000000000..e53588fc38
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/extended_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.
+ */
+
+#pragma once
+
+#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 0000000000..7ae4facc5f
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/filebrowser.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.
+ */
+
+#pragma once
+
+#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 0000000000..fc3c34cecf
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/keyboard.h
@@ -0,0 +1,74 @@
+/*
+ * 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
+
+#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 0000000000..df23cd74a4
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/numeric.h
@@ -0,0 +1,54 @@
+/*
+ * 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
+
+#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 0000000000..9f37051de9
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/ok.h
@@ -0,0 +1,37 @@
+/*
+ * 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
+
+#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 0000000000..f1c8972dec
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/progress.h
@@ -0,0 +1,45 @@
+/*
+ * 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
+
+#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 0000000000..41ab82f9a2
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/select.h
@@ -0,0 +1,42 @@
+/*
+ * 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
+
+#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 0000000000..eb38b0be7f
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/text_viewer.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.
+ */
+
+#pragma once
+
+#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 0000000000..01ed80622f
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/dialogs/yes_no.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.
+ */
+
+#pragma once
+
+#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 0000000000..d0d256c55e
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/general.h
@@ -0,0 +1,37 @@
+/*
+ * 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
+
+#ifndef C_API_GUI_GENERAL_H
+#define C_API_GUI_GENERAL_H
+
+#include "definitions.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ 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);
+ } 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 0000000000..c0bbd11937
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(HEADERS action_ids.h)
+
+if(NOT ENABLE_STATIC_LIBS)
+ core_add_library(addons_kodi-dev-kit_include_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 0000000000..274f3d9227
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/input/action_ids.h
@@ -0,0 +1,763 @@
+/*
+ * 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
+
+#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 0000000000..f0c4dc73d3
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/list_item.h
@@ -0,0 +1,54 @@
+/*
+ * 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
+
+#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 0000000000..0f844f5e9d
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/gui/window.h
@@ -0,0 +1,183 @@
+/*
+ * 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
+
+#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/platform/android/system.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/platform/android/system.h
new file mode 100644
index 0000000000..568a2fd5ee
--- /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.
+ */
+
+#pragma once
+
+#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
index 125cca52b0..8f12955a5e 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/CMakeLists.txt
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/CMakeLists.txt
@@ -1,7 +1,6 @@
set(HEADERS General.h
ListItem.h
Window.h
- definitions.h
renderHelper.h)
if(NOT ENABLE_STATIC_LIBS)
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h
index b5a6393774..85ba3f235f 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/General.h
@@ -9,167 +9,168 @@
#pragma once
#include "../AddonBase.h"
-#include "definitions.h"
+#include "../c-api/gui/general.h"
+
+#ifdef __cplusplus
namespace kodi
{
namespace gui
{
- //============================================================================
- ///
- // \defgroup cpp_kodi_gui ::general
- /// \addtogroup cpp_kodi_gui
- /// @{
- /// @brief **Allow use of binary classes and function to use on add-on's**
- ///
- /// Permits the use of the required functions of the add-on to Kodi. This class
- /// also contains some functions to the control.
- ///
- /// 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
- /// @brief Performs a graphical lock of rendering engine
- ///
- inline void ATTRIBUTE_HIDDEN Lock()
- {
- using namespace ::kodi::addon;
- CAddonBase::m_interface->toKodi->kodi_gui->general->lock();
- }
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN Lock()
+{
+ using namespace ::kodi::addon;
+ CAddonBase::m_interface->toKodi->kodi_gui->general->lock();
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui
- /// @brief Performs a graphical unlock of previous locked rendering engine
- ///
- inline void ATTRIBUTE_HIDDEN Unlock()
- {
- using namespace ::kodi::addon;
- CAddonBase::m_interface->toKodi->kodi_gui->general->unlock();
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Performs a graphical unlock of previous locked rendering engine.
+///
+inline void ATTRIBUTE_HIDDEN Unlock()
+{
+ using namespace ::kodi::addon;
+ CAddonBase::m_interface->toKodi->kodi_gui->general->unlock();
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui
- /// @brief Return the the current screen height with pixel
- ///
- inline int ATTRIBUTE_HIDDEN GetScreenHeight()
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->general->get_screen_height(CAddonBase::m_interface->toKodi->kodiBase);
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Return the the current screen height with pixel.
+///
+/// @return Screen height with pixel
+///
+inline int ATTRIBUTE_HIDDEN GetScreenHeight()
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->general->get_screen_height(
+ CAddonBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui
- /// @brief Return the the current screen width with pixel
- ///
- inline int ATTRIBUTE_HIDDEN GetScreenWidth()
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->general->get_screen_width(CAddonBase::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 ATTRIBUTE_HIDDEN GetScreenWidth()
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->general->get_screen_width(
+ CAddonBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui
- /// @brief Return the the current screen rendering resolution
- ///
- inline int ATTRIBUTE_HIDDEN GetVideoResolution()
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->general->get_video_resolution(CAddonBase::m_interface->toKodi->kodiBase);
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @ingroup cpp_kodi_gui_general
+/// @brief Return the the current screen rendering resolution.
+///
+/// @return Current screen rendering resolution
+///
+inline int ATTRIBUTE_HIDDEN GetVideoResolution()
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->general->get_video_resolution(
+ CAddonBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui
- /// @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 ATTRIBUTE_HIDDEN GetCurrentWindowDialogId()
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->general->get_current_window_dialog_id(CAddonBase::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 ATTRIBUTE_HIDDEN GetCurrentWindowDialogId()
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->general->get_current_window_dialog_id(
+ CAddonBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui
- /// @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 ATTRIBUTE_HIDDEN GetCurrentWindowId()
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->general->get_current_window_id(CAddonBase::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 ATTRIBUTE_HIDDEN GetCurrentWindowId()
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->general->get_current_window_id(
+ CAddonBase::m_interface->toKodi->kodiBase);
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui
- /// \brief To get hardware specific device context interface
- ///
- /// \return The currently active device context
- ///
- /// \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 void* GetHWContext()
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->general->get_hw_context(CAddonBase::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 CAddonBase::m_interface->toKodi->kodi_gui->general->get_hw_context(
+ CAddonBase::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
index 1af48639fb..3a4d50be2c 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/ListItem.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/ListItem.h
@@ -9,7 +9,9 @@
#pragma once
#include "../AddonBase.h"
-#include "definitions.h"
+#include "../c-api/gui/list_item.h"
+
+#ifdef __cplusplus
#include <memory>
@@ -18,349 +20,326 @@ namespace kodi
namespace gui
{
- class CWindow;
+class CWindow;
- class ATTRIBUTE_HIDDEN CAddonGUIControlBase
- {
- public:
- GUIHANDLE GetControlHandle() const { return m_controlHandle; }
+class ATTRIBUTE_HIDDEN CAddonGUIControlBase
+{
+public:
+ KODI_GUI_LISTITEM_HANDLE GetControlHandle() const { return m_controlHandle; }
- protected:
- explicit CAddonGUIControlBase(CAddonGUIControlBase* window)
+protected:
+ explicit CAddonGUIControlBase(CAddonGUIControlBase* window)
: m_controlHandle(nullptr),
m_interface(::kodi::addon::CAddonBase::m_interface->toKodi),
- m_Window(window) {}
+ m_Window(window)
+ {
+ }
- virtual ~CAddonGUIControlBase() = default;
+ virtual ~CAddonGUIControlBase() = default;
- friend class CWindow;
+ friend class CWindow;
- GUIHANDLE m_controlHandle;
- AddonToKodiFuncTable_Addon* m_interface;
- CAddonGUIControlBase* m_Window;
+ 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;
- };
+private:
+ CAddonGUIControlBase() = delete;
+ CAddonGUIControlBase(const CAddonGUIControlBase&) = delete;
+ CAddonGUIControlBase& operator=(const CAddonGUIControlBase&) = delete;
+};
- class CListItem;
- typedef std::shared_ptr<CListItem> ListItemPtr;
+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 ATTRIBUTE_HIDDEN CListItem : public CAddonGUIControlBase
+{
+public:
//============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief Class constructor with parameters.
///
- /// \defgroup cpp_kodi_gui_CListItem List Item
- /// \ingroup cpp_kodi_gui
- /// @brief \cpp_class{ kodi::gui::CListItem }
- /// **Selectable window list item**
- ///
- /// The list item control is used for creating item lists in Kodi
+ /// @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
///
- /// 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.
+ 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.
///
- /// \defgroup cpp_kodi_gui_CListItem_Defs Definitions, structures and enumerators
- /// \ingroup cpp_kodi_gui_CListItem
- /// @brief **Library definition values**
+ /// @return Label of item
///
-
- class ATTRIBUTE_HIDDEN CListItem : public CAddonGUIControlBase
+ std::string GetLabel()
{
- public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @brief Class constructor with parameters
- ///
- /// @param[in] label Item label
- /// @param[in] label2 Second Item label (if needed)
- /// @param[in] iconImage Item icon image (if needed)
- /// @param[in] path Path to where item is defined
- ///
- CListItem(
- const std::string& label = "",
- const std::string& label2 = "",
- const std::string& iconImage = "",
- const std::string& path = "")
- : CAddonGUIControlBase(nullptr)
- {
- m_controlHandle = m_interface->kodi_gui->listItem->create(m_interface->kodiBase, label.c_str(),
- label2.c_str(), iconImage.c_str(),
- path.c_str());
- }
-
- /*
- * Constructor used for parts given by list items from addon window
- *
- * Related to call of "ListItemPtr kodi::gui::CWindow::GetListItem(int listPos)"
- * Not needed for addon development itself
- */
- explicit CListItem(GUIHANDLE listItemHandle)
- : CAddonGUIControlBase(nullptr)
- {
- m_controlHandle = listItemHandle;
- }
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @brief Class destructor
- ///
- ~CListItem() override
- {
- m_interface->kodi_gui->listItem->destroy(m_interface->kodiBase, m_controlHandle);
- }
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @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)
{
- 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;
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
}
- //--------------------------------------------------------------------------
+ return label;
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @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_CListItem
- /// @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 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_CListItem
- /// @brief Sets the listitem's label2.
- ///
- /// @param[in] label string or unicode - text string.
- ///
- void SetLabel2(const std::string& label)
+ //============================================================================
+ /// @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)
{
- m_interface->kodi_gui->listItem->set_label2(m_interface->kodiBase, m_controlHandle, label.c_str());
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
}
- //--------------------------------------------------------------------------
+ return label;
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @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 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_CListItem
- /// @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)
+ //============================================================================
+ /// @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)
{
- m_interface->kodi_gui->listItem->set_art(m_interface->kodiBase, m_controlHandle, type.c_str(), url.c_str());
+ if (std::strlen(ret))
+ strReturn = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
}
- //--------------------------------------------------------------------------
+ return strReturn;
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @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 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_CListItem
- /// @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)
+ //============================================================================
+ /// @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)
{
- m_interface->kodi_gui->listItem->set_path(m_interface->kodiBase, m_controlHandle, path.c_str());
+ if (std::strlen(ret))
+ strReturn = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
}
- //--------------------------------------------------------------------------
+ return strReturn;
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @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 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_CListItem
- /// @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 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_CListItem
- /// @brief To control selection of item in list (also multiple selection,
- /// in list on serveral items possible).
- ///
- /// @param[in] selected if true becomes set as selected
- ///
- void Select(bool selected)
+ //============================================================================
+ /// @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)
{
- m_interface->kodi_gui->listItem->select(m_interface->kodiBase, m_controlHandle, selected);
+ if (std::strlen(ret))
+ label = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
}
- //--------------------------------------------------------------------------
+ return label;
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CListItem
- /// @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);
- }
- //--------------------------------------------------------------------------
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_listitem
+ /// @brief To control selection of item in list (also multiple selection,
+ /// in list on serveral 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
index 5011374528..3066b3c2e9 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/Window.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/Window.h
@@ -9,901 +9,907 @@
#pragma once
#include "../AddonBase.h"
+#include "../c-api/gui/window.h"
#include "ListItem.h"
+#include "input/ActionIDs.h"
-#ifdef BUILD_KODI_ADDON
-#include "../ActionIDs.h"
-#else
-#include "input/actions/ActionIDs.h"
-#endif
+#ifdef __cplusplus
namespace kodi
{
namespace gui
{
- class CListItem;
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN 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.
///
- /// \defgroup cpp_kodi_gui_CWindow Window
- /// \ingroup cpp_kodi_gui
- /// @brief \cpp_class{ kodi::gui::CWindow }
- /// **Main window control class**
+ /// Shows this window by activating it, calling close() after it wil activate
+ /// the current window again.
///
- /// The with \ref Window.h "#include <kodi/gui/Window.h>"
- /// included file brings support to create a window or dialog on Kodi.
+ /// @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.
///
- /// 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.
+ /// @return Return true if call and show is successed, if false was something
+ /// failed to get needed skin parts.
///
- /// ~~~~~~~~~~~~~{.xml}
- /// <control type="label" id="31">
- /// <description>Title Label</description>
- /// ...
- /// </control>
- /// <control type="progress" id="32">
- /// <description>progress control</description>
- /// ...
- /// </control>
- /// ~~~~~~~~~~~~~
+ 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.
///
- /// \defgroup cpp_kodi_gui_CWindow_Defs Definitions, structures and enumerators
- /// \ingroup cpp_kodi_gui_CWindow
- /// @brief <b>Library definition values</b>
+ 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);
+ }
+ //----------------------------------------------------------------------------
- class ATTRIBUTE_HIDDEN CWindow : public CAddonGUIControlBase
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_window
+ /// @brief Returns the id of the control which is focused.
+ ///
+ /// @return Focused control id
+ ///
+ int GetFocusId()
{
- public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow
- /// @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 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_CWindow
- /// @brief Show this window.
- ///
- /// Shows this window by activating it, calling close() after it wil 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 doModal() instead.
- ///
- /// @warning If used must be the class be global present until Kodi becomes
- /// closed. The creation can be done after before "Show" becomes called, but
- /// not delete class after them.
- ///
- /// @return Return true if call and show is successed,
- /// if false was something failed to get needed
- /// skin parts.
- ///
- bool Show()
- {
- return m_interface->kodi_gui->window->show(m_interface->kodiBase, m_controlHandle);
- }
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @brief Gives the control with the supplied focus.
- ///
- /// @param[in] iControlId 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 iControlId)
- {
- return m_interface->kodi_gui->window->set_focus_id(m_interface->kodiBase, m_controlHandle, iControlId);
- }
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @brief Returns a window property as a string, similar to an infolabel.
- ///
- /// @param[in] key string - property name.
- /// @return The property as strin (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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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(ListItemPtr 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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @brief Remove item with given control class from list.
- ///
- /// @param[in] item List item control class to remove
- ///
- ///
- void RemoveListItem(ListItemPtr item)
- {
- m_interface->kodi_gui->window->remove_list_item(m_interface->kodiBase, m_controlHandle, item->m_controlHandle);
- }
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow
- /// @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!
- ///
- ListItemPtr GetListItem(int listPos)
- {
- GUIHANDLE handle = m_interface->kodi_gui->window->get_list_item(m_interface->kodiBase, m_controlHandle, listPos);
- if (!handle)
- return ListItemPtr();
+ return m_interface->kodi_gui->window->get_focus_id(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
- return std::make_shared<kodi::gui::CListItem>(handle);
- }
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow
- /// @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_CWindow_callbacks Callback functions from Kodi to add-on
- /// \ingroup cpp_kodi_gui_CWindow
- //@{
- /// @brief <b>GUI window callback functions.</b>
- ///
- /// Functions to handle control callbacks from Kodi
- ///
- /// ------------------------------------------------------------------------
- ///
- /// @link cpp_kodi_gui_CWindow Go back to normal functions from CWindow@endlink
- //
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow_callbacks
- /// @brief OnInit method.
- ///
- /// @return Return true if initialize was done successful
- ///
- ///
- virtual bool OnInit() { return false; }
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow_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_CWindow_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_CWindow_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 PREVIOUS_MENU and \c NAV_BACK actions are handled.
- /// - Overwrite this method to let your code handle all actions.
- /// - Don't forget to capture \c ACTION_PREVIOUS_MENU or \c ACTION_NAV_BACK, else the user can't close this window.
- ///
- ///
- ///--------------------------------------------------------------------------
- ///
- /// **Example:**
- /// ~~~~~~~~~~~~~{.cpp}
- /// ..
- /// /* Window used with parent / child way */
- /// bool cYOUR_CLASS::OnAction(int actionId)
- /// {
- /// switch (action)
- /// {
- /// case ACTION_PREVIOUS_MENU:
- /// case ACTION_NAV_BACK:
- /// printf("action recieved: previous");
- /// Close();
- /// return true;
- /// case ACTION_SHOW_INFO:
- /// printf("action recieved: show info");
- /// break;
- /// case ACTION_STOP:
- /// printf("action recieved: stop");
- /// break;
- /// case ACTION_PAUSE:
- /// printf("action recieved: pause");
- /// break;
- /// default:
- /// break;
- /// }
- /// return false;
- /// }
- /// ..
- /// ~~~~~~~~~~~~~
- ///
- virtual bool OnAction(int actionId, uint32_t buttoncode, wchar_t unicode)
- {
- switch (actionId)
- {
- case ACTION_PREVIOUS_MENU:
- case ACTION_NAV_BACK:
- Close();
- return true;
- default:
- break;
- }
- return false;
- }
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_CWindow_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_CWindow_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_CWindow_callbacks
- /// @brief **Set independent callbacks**
- ///
- /// If the class is used independent (with "new CWindow") and
- /// not as parent (with "cCLASS_own : 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(GUIHANDLE cbhdl)
- /// {
- /// ...
- /// return true;
- /// }
- ///
- /// bool OnFocus(GUIHANDLE cbhdl, int controlId)
- /// {
- /// ...
- /// return true;
- /// }
- ///
- /// bool OnClick(GUIHANDLE cbhdl, int controlId)
- /// {
- /// ...
- /// return true;
- /// }
- ///
- /// bool OnAction(GUIHANDLE cbhdl, int actionId)
- /// {
- /// ...
- /// return true;
- /// }
- ///
- /// ...
- /// /* Somewhere where you create the window */
- /// CWindow myWindow = new CWindow;
- /// myWindow->SetIndependentCallbacks(myWindow, OnInit, OnFocus, OnClick, OnAction);
- /// ...
- /// ~~~~~~~~~~~~~
- ///
- void SetIndependentCallbacks(
- GUIHANDLE cbhdl,
- bool (*CBOnInit) (GUIHANDLE cbhdl),
- bool (*CBOnFocus) (GUIHANDLE cbhdl, int controlId),
- bool (*CBOnClick) (GUIHANDLE cbhdl, int controlId),
- bool (*CBOnAction) (GUIHANDLE cbhdl, int actionId, uint32_t buttoncode, wchar_t unicode),
- void (*CBGetContextButtons) (GUIHANDLE cbhdl, int itemNumber, gui_context_menu_pair* buttons, unsigned int* size) = nullptr,
- bool (*CBOnContextButton) (GUIHANDLE 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;
- }
+ //============================================================================
+ /// @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());
+ }
+ //----------------------------------------------------------------------------
- m_interface->kodi_gui->window->set_callbacks(m_interface->kodiBase, m_controlHandle, cbhdl,
- CBOnInit, CBOnFocus, CBOnClick, CBOnAction,
- CBGetContextButtons, CBOnContextButton);
- }
- //--------------------------------------------------------------------------
- //@}
+ //============================================================================
+ /// @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);
+ }
+ //----------------------------------------------------------------------------
- private:
- static bool CBOnInit(GUIHANDLE cbhdl)
- {
- return static_cast<CWindow*>(cbhdl)->OnInit();
- }
+ //============================================================================
+ /// @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());
+ }
+ //----------------------------------------------------------------------------
- static bool CBOnFocus(GUIHANDLE cbhdl, int controlId)
+ //============================================================================
+ /// @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)
{
- return static_cast<CWindow*>(cbhdl)->OnFocus(controlId);
+ 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);
+ }
+ //----------------------------------------------------------------------------
- static bool CBOnClick(GUIHANDLE cbhdl, int controlId)
+ //============================================================================
+ /// @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(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(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 recieved: previous");
+ /// Close();
+ /// return true;
+ /// case ADDON_ACTION_SHOW_INFO:
+ /// printf("action recieved: show info");
+ /// break;
+ /// case ADDON_ACTION_STOP:
+ /// printf("action recieved: stop");
+ /// break;
+ /// case ADDON_ACTION_PAUSE:
+ /// printf("action recieved: pause");
+ /// break;
+ /// default:
+ /// break;
+ /// }
+ /// return false;
+ /// }
+ /// ..
+ /// ~~~~~~~~~~~~~
+ ///
+ virtual bool OnAction(ADDON_ACTION actionId)
+ {
+ switch (actionId)
{
- return static_cast<CWindow*>(cbhdl)->OnClick(controlId);
+ case ADDON_ACTION_PREVIOUS_MENU:
+ case ADDON_ACTION_NAV_BACK:
+ Close();
+ return true;
+ default:
+ break;
}
+ return false;
+ }
+ //----------------------------------------------------------------------------
- static bool CBOnAction(GUIHANDLE cbhdl, int actionId, uint32_t buttoncode, wchar_t unicode)
+ //============================================================================
+ /// @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)
{
- return static_cast<CWindow*>(cbhdl)->OnAction(actionId, buttoncode, unicode);
+ kodi::Log(ADDON_LOG_FATAL, "kodi::gui::CWindow::%s called with nullptr !!!", __FUNCTION__);
+ return;
}
- static void CBGetContextButtons(GUIHANDLE 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())
+ 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)
{
- 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);
- }
+ buttons[i].id = buttonList[i].first;
+ strncpy(buttons[i].name, buttonList[i].second.c_str(), ADDON_MAX_CONTEXT_ENTRY_NAME_LENGTH);
}
}
+ }
- static bool CBOnContextButton(GUIHANDLE cbhdl, int itemNumber, unsigned int button)
- {
- return static_cast<CWindow*>(cbhdl)->OnContextButton(itemNumber, button);
- }
- };
+ 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
index 081ab06d6f..873a549d2a 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Button.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Button.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/button.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,35 +20,33 @@ namespace gui
namespace controls
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CButton Control Button
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CButton }
-/// **Standard push button control for window**
+//==============================================================================
+/// @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.
///
-/// 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.
+/// 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>"
+/// 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"
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
class ATTRIBUTE_HIDDEN CButton : public CAddonGUIControlBase
{
public:
- //==========================================================================
- ///
- /// @ingroup cpp_kodi_gui_control_CButton
- /// @brief Construct a new control
+ //============================================================================
+ /// @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
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CButton(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -55,64 +55,59 @@ public:
if (!m_controlHandle)
kodi::Log(ADDON_LOG_FATAL, "kodi::gui::CButton can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// @ingroup cpp_kodi_gui_control_CButton
- /// @brief Destructor
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Destructor.
///
~CButton() override = default;
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// @ingroup cpp_kodi_gui_control_CButton
- /// @brief Set the control on window to visible
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Set the control on window to visible.
///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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_control_CButton
- /// @brief Set's the control's enabled/disabled state
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Set's the control's enabled/disabled state.
///
- /// @param[in] enabled If true enabled, otherwise disabled
+ /// @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.
///
- /// @ingroup cpp_kodi_gui_control_CButton
- /// @brief To set the text string on button
- ///
- /// @param[in] label Text to show
+ /// @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_control_CButton
- /// @brief Get the used text from button
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CButton
+ /// @brief Get the used text from button.
///
- /// @return Text shown
+ /// @return Text shown
///
std::string GetLabel() const
{
@@ -127,28 +122,26 @@ public:
}
return label;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// @ingroup cpp_kodi_gui_control_CButton
- /// @brief If two labels are used for button becomes it set with them
+ //============================================================================
+ /// @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
+ /// @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.
///
- /// @ingroup cpp_kodi_gui_control_CButton
- /// @brief Get the second label if present
- ///
- /// @return Second label
+ /// @return Second label
///
std::string GetLabel2() const
{
@@ -163,9 +156,11 @@ public:
}
return label;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
};
} /* namespace controls */
} /* namespace gui */
} /* namespace kodi */
+
+#endif /* __cplusplus */
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
index 99c01de413..00c6231ce3 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Edit.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Edit.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/edit.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,93 +20,43 @@ namespace gui
namespace controls
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_controls_CEdit Control Edit
- /// \ingroup cpp_kodi_gui
- /// @brief \cpp_class{ kodi::gui::controls::CEdit }
- /// **Editable window text control used as an input control for the osd keyboard
- /// and other input fields**
- ///
- /// 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 part for 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_controls_CEdit_Defs"
- ///
- /// \defgroup cpp_kodi_gui_controls_CEdit_Defs Definitions, structures and enumerators
- /// \ingroup cpp_kodi_gui_controls_CEdit
- /// @brief **Library definition values**
- ///
-
-} /* namespace controls */
-} /* namespace gui */
-} /* namespace kodi */
-
-//============================================================================
+//==============================================================================
+/// @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.
///
-/// \ingroup cpp_kodi_gui_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
-};
-/// @}
-//----------------------------------------------------------------------------
-namespace kodi
-{
-namespace gui
-{
-namespace controls
-{
+//==============================================================================
+// 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 ATTRIBUTE_HIDDEN CEdit : public CAddonGUIControlBase
{
public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CEdit
- /// @brief Construct a new control
+ //============================================================================
+ /// @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
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CEdit(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -114,64 +66,59 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::control::CEdit can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CEdit
- /// @brief Destructor
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Destructor.
///
~CEdit() override = default;
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CEdit
- /// @brief Set the control on window to visible
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Set the control on window to visible.
///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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_controls_CEdit
- /// @brief Set's the control's enabled/disabled state
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief Set's the control's enabled/disabled state.
///
- /// @param[in] enabled If true enabled, otherwise disabled
+ /// @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_controls_CEdit
- /// @brief To set the text string on edit control
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief To set the text string on edit control.
///
- /// @param[in] label Text to show
+ /// @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_controls_CEdit
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
/// @brief Returns the text heading for this edit control.
///
- /// @return Heading text
+ /// @return Heading text
///
std::string GetLabel() const
{
@@ -186,11 +133,10 @@ public:
}
return label;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CEdit
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
/// @brief Set's text heading for this edit control.
///
/// @param[in] text string or unicode - text string.
@@ -200,14 +146,13 @@ public:
m_interface->kodi_gui->control_edit->set_text(m_interface->kodiBase, m_controlHandle,
text.c_str());
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CEdit
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
/// @brief Returns the text value for this edit control.
///
- /// @return Text value of control
+ /// @return Text value of control
///
std::string GetText() const
{
@@ -222,54 +167,51 @@ public:
}
return text;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CEdit
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
/// @brief Set the cursor position on text.
///
- /// @param[in] iPosition The position to set
+ /// @param[in] position The position to set
///
- void SetCursorPosition(unsigned int iPosition)
+ void SetCursorPosition(unsigned int position)
{
m_interface->kodi_gui->control_edit->set_cursor_position(m_interface->kodiBase, m_controlHandle,
- iPosition);
+ position);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CEdit
- /// @brief To get current cursor position on text field
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CEdit
+ /// @brief To get current cursor position on text field.
///
- /// @return The current cursor position
+ /// @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_controls_CEdit
- /// @brief To set field input type which are defined on \ref AddonGUIInputType
+ //============================================================================
+ /// @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
+ /// @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
index 02c843f27f..01847fbd74 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/FadeLabel.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/FadeLabel.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/fade_label.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,40 +20,38 @@ namespace gui
namespace controls
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CFadeLabel Control Fade Label
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CFadeLabel }
+//==============================================================================
+/// @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**
+/// 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.
///
-/// 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.
+/// 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>"
+/// 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"
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
class ATTRIBUTE_HIDDEN CFadeLabel : public CAddonGUIControlBase
{
public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CFadeLabel
+ //============================================================================
+ /// @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
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CFadeLabel(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -61,50 +61,46 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::controls::CFadeLabel can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CFadeLabel
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
/// @brief Destructor.
///
~CFadeLabel() override = default;
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CFadeLabel
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
/// @brief Set the control on window to visible.
///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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_controls_CFadeLabel
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
/// @brief To add additional text string on fade label.
///
- /// @param[in] label Text to show
+ /// @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_controls_CFadeLabel
- /// @brief Get the used text from button
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CFadeLabel
+ /// @brief Get the used text from button.
///
- /// @return Text shown
+ /// @return Text shown
///
std::string GetLabel() const
{
@@ -119,35 +115,34 @@ public:
}
return label;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CFadeLabel
- /// @brief To enable or disable scrolling on fade 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
+ /// @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_controls_CFadeLabel
+ //============================================================================
+ /// @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
index b4d092f111..9dc493e3eb 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Image.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Image.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/image.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -19,33 +21,30 @@ namespace controls
{
//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CImage Control Image
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CImage }
-/// **Window control used to show an image.**
-///
-/// The image control is used for displaying images in Kodi. You can choose
+/// @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>"
+/// 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"
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
class ATTRIBUTE_HIDDEN CImage : public CAddonGUIControlBase
{
public:
//==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CImage
+ /// @brief Construct a new control.
///
- /// \ingroup cpp_kodi_gui_controls_CImage
- /// @brief Construct a new control
- ///
- /// @param[in] window related window control class
- /// @param[in] controlId Used skin xml control id
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CImage(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -58,19 +57,17 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CImage
- /// @brief Destructor
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CImage
- /// @brief Set the control on window to visible
- ///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @param[in] visible If true visible, otherwise hidden
///
void SetVisible(bool visible)
{
@@ -80,14 +77,12 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CImage
+ /// @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
+ /// @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)
{
@@ -97,11 +92,10 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CImage
+ /// @ingroup cpp_kodi_gui_windows_controls_CImage
/// @brief To set set the diffuse color on image.
///
- /// @param[in] colorDiffuse Color to use for diffuse
+ /// @param[in] colorDiffuse Color to use for diffuse
///
void SetColorDiffuse(uint32_t colorDiffuse)
{
@@ -114,3 +108,5 @@ public:
} /* 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
index 82604bd48e..d10b85f4b7 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Label.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Label.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/label.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,34 +20,31 @@ namespace gui
namespace controls
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CLabel Control Label
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CLabel }
-/// **Window control used to show some lines of text.**
-///
-/// The label control is used for displaying text in Kodi. You can choose
+//==============================================================================
+/// @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>"
+/// 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"
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
class ATTRIBUTE_HIDDEN CLabel : public CAddonGUIControlBase
{
public:
- //==========================================================================
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CLabel
+ /// @brief Construct a new control.
///
- /// \ingroup cpp_kodi_gui_controls_CLabel
- /// @brief Construct a new control
- ///
- /// @param[in] window related window control class
- /// @param[in] controlId Used skin xml control id
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CLabel(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -55,50 +54,46 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::controls::CLabel can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CLabel
- /// @brief Destructor
+ //============================================================================
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CLabel
- /// @brief Set the control on window to visible
- ///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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_controls_CLabel
- /// @brief To set the text string on label
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CLabel
+ /// @brief To set the text string on label.
///
- /// @param[in] text Text to show
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CLabel
- /// @brief Get the used text from control
- ///
- /// @return Used text on label control
+ /// @return Used text on label control
///
std::string GetLabel() const
{
@@ -113,9 +108,11 @@ public:
}
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
index 8cb582bbb4..83b16aae83 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Progress.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Progress.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/progress.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,21 +20,20 @@ namespace gui
namespace controls
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CProgress Control Progress
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CProgress }
-/// **Window control to show the progress of a particular operation**
-///
+//==============================================================================
+/// @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.
+/// a long time, or to show how far through a movie you are.
///
-/// It has the header \ref Progress.h "#include <kodi/gui/controls/Progress.h>"
+/// 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"
+/// 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.
@@ -40,13 +41,12 @@ namespace controls
class ATTRIBUTE_HIDDEN CProgress : public CAddonGUIControlBase
{
public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CProgress
- /// @brief Construct a new control
+ //============================================================================
+ /// @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
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CProgress(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -56,59 +56,57 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::controls::CProgress can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CProgress
- /// @brief Destructor
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief Destructor.
///
~CProgress() override = default;
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CProgress
- /// @brief Set the control on window to visible
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief Set the control on window to visible.
///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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_controls_CProgress
- /// @brief To set Percent position of control
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CProgress
+ /// @brief To set Percent position of control.
///
- /// @param[in] percent The percent position to use
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CProgress
- /// @brief Get the active percent position of progress bar
- ///
- /// @return Progress position as percent
+ /// @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
index 305195d46b..3b6a23c13b 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/RadioButton.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/RadioButton.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/radio_button.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,36 +20,87 @@ namespace gui
namespace controls
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CRadioButton Control Radio Button
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CRadioButton }
-/// **Window control for a radio button (as used for on/off settings)**
+//==============================================================================
+/// @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.
///
-/// 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
+/// 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>"
+/// 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"
+/// 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
+/// @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 ATTRIBUTE_HIDDEN CRadioButton : public CAddonGUIControlBase
{
public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CRadioButton
- /// @brief Construct a new control
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Construct a new control.
///
- /// @param[in] window related window control class
+ /// @param[in] window Related window control class
/// @param[in] controlId Used skin xml control id
///
CRadioButton(CWindow* window, int controlId) : CAddonGUIControlBase(window)
@@ -58,64 +111,59 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::controls::CRadioButton can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CRadioButton
- /// @brief Destructor
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Destructor.
///
~CRadioButton() override = default;
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CRadioButton
- /// @brief Set the control on window to visible
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton.
+ /// @brief Set the control on window to visible.
///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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_controls_CRadioButton
- /// @brief Set's the control's enabled/disabled state
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Set's the control's enabled/disabled state.
///
- /// @param[in] enabled If true enabled, otherwise disabled
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CRadioButton
- /// @brief To set the text string on radio button
- ///
- /// @param[in] label Text to show
+ /// @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_controls_CRadioButton
- /// @brief Get the used text from control
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRadioButton
+ /// @brief Get the used text from control.
///
- /// @return Text shown
+ /// @return Text shown
///
std::string GetLabel() const
{
@@ -130,38 +178,37 @@ public:
}
return label;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CRadioButton
- /// @brief To set radio button condition to on or off
+ //============================================================================
+ /// @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
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CRadioButton
- /// @brief Get the current selected condition of radio button
- ///
- /// @return Selected condition
+ /// @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
index 7cc9b247d9..7f5feef3b5 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Rendering.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Rendering.h
@@ -8,10 +8,12 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/rendering.h"
#include "../Window.h"
#include "../renderHelper.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -20,46 +22,36 @@ 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.
///
-/// \defgroup cpp_kodi_gui_controls_CRendering Control Rendering
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CRendering }
-/// **Window control for rendering own parts**
-///
-/// 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.
+/// 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.
+/// 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>"
+/// 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"
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
-
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CRendering_Defs Definitions, structures and enumerators
-/// \ingroup cpp_kodi_gui_controls_CRendering
-/// @brief **Library definition values**
-///
-
class ATTRIBUTE_HIDDEN CRendering : public CAddonGUIControlBase
{
public:
//==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief Construct a new control.
///
- /// \ingroup cpp_kodi_gui_controls_CRendering
- /// @brief Construct a new control
- ///
- /// @param[in] window related window control class
- /// @param[in] controlId Used skin xml control id
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CRendering(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -76,9 +68,8 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CRendering
- /// @brief Destructor
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief Destructor.
///
~CRendering() override
{
@@ -87,76 +78,91 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CRendering
+ /// @brief To create rendering control on Add-on.
///
- /// \ingroup cpp_kodi_gui_controls_CRendering
- /// @brief To create rendering control on Add-on
- ///
- /// Function creates the needed rendering control for Kodi which becomes
+ /// 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
+ /// @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.
+ /// @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.
///
- virtual bool Create(int x, int y, int w, int h, void* device) { return 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.
///
- /// \ingroup cpp_kodi_gui_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.
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CRendering
- /// @brief Call from Kodi to stop rendering process
- ///
- /// @note This is callback function from Kodi to Add-on and not to use
+ /// @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_controls_CRendering
- /// @brief Call from Kodi where add-on becomes asked about dirty rendering
+ /// @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
+ /// @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_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
+ /// @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!
///
- void SetIndependentCallbacks(
- GUIHANDLE cbhdl,
- bool (*CBCreate)(GUIHANDLE cbhdl, int x, int y, int w, int h, void* device),
- void (*CBRender)(GUIHANDLE cbhdl),
- void (*CBStop)(GUIHANDLE cbhdl),
- bool (*CBDirty)(GUIHANDLE cbhdl))
+ /// @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)
{
@@ -174,13 +180,14 @@ private:
* Defined callback functions from Kodi to add-on, for use in parent / child system
* (is private)!
*/
- static bool OnCreateCB(void* cbhdl, int x, int y, int w, int h, void* device)
+ 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(void* cbhdl)
+ static void OnRenderCB(KODI_GUI_CLIENT_HANDLE cbhdl)
{
if (!static_cast<CRendering*>(cbhdl)->m_renderHelper)
return;
@@ -189,13 +196,16 @@ private:
static_cast<CRendering*>(cbhdl)->m_renderHelper->End();
}
- static void OnStopCB(void* cbhdl)
+ static void OnStopCB(KODI_GUI_CLIENT_HANDLE cbhdl)
{
static_cast<CRendering*>(cbhdl)->Stop();
static_cast<CRendering*>(cbhdl)->m_renderHelper = nullptr;
}
- static bool OnDirtyCB(void* cbhdl) { return static_cast<CRendering*>(cbhdl)->Dirty(); }
+ static bool OnDirtyCB(KODI_GUI_CLIENT_HANDLE cbhdl)
+ {
+ return static_cast<CRendering*>(cbhdl)->Dirty();
+ }
std::shared_ptr<kodi::gui::IRenderHelper> m_renderHelper;
};
@@ -203,3 +213,5 @@ private:
} /* 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
index 76a02aad9a..5557fc400b 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/SettingsSlider.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/SettingsSlider.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/settings_slider.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,37 +20,36 @@ namespace gui
namespace controls
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CSettingsSlider Control Settings Slider
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CSettingsSlider }
-/// **Window control for moveable slider with text name**
+//==============================================================================
+/// @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.
///
-/// 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.
+/// 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>"
+/// 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"
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
class ATTRIBUTE_HIDDEN CSettingsSlider : public CAddonGUIControlBase
{
public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
- /// @brief Construct a new control
+ //============================================================================
+ /// @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
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CSettingsSlider(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -58,74 +59,68 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::controls::CSettingsSlider can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
- /// @brief Destructor
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Destructor.
///
~CSettingsSlider() override = default;
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
- /// @brief Set the control on window to visible
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief Set the control on window to visible.
///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
- /// @brief Set's the control's enabled/disabled state
- ///
- /// @param[in] enabled If true enabled, otherwise disabled
+ /// @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_controls_CSettingsSlider
- /// @brief To set the text string on settings slider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
+ /// @brief To set the text string on settings slider.
///
- /// @param[in] text Text to show
+ /// @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_controls_CSettingsSlider
- /// @brief To reset slider on defaults
+ //============================================================================
+ /// @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_controls_CSettingsSlider
+ //============================================================================
+ /// @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
+ /// 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.
@@ -133,11 +128,11 @@ public:
/// 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
+ /// @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
+ /// @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)
@@ -145,18 +140,17 @@ public:
m_interface->kodi_gui->control_settings_slider->set_int_range(m_interface->kodiBase,
m_controlHandle, start, end);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
- /// @brief Set the slider position with the given integer value. The Range
- /// must be defined with a call from \ref SetIntRange before.
+ //============================================================================
+ /// @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
+ /// @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
+ /// @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)
@@ -164,17 +158,16 @@ public:
m_interface->kodi_gui->control_settings_slider->set_int_value(m_interface->kodiBase,
m_controlHandle, value);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
/// @brief To get the current position as integer value.
///
- /// @return The position as integer
+ /// @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
+ /// @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
@@ -182,19 +175,18 @@ public:
return m_interface->kodi_gui->control_settings_slider->get_int_value(m_interface->kodiBase,
m_controlHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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
+ //============================================================================
+ /// @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.
+ /// @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
+ /// @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)
@@ -202,17 +194,16 @@ public:
m_interface->kodi_gui->control_settings_slider->set_int_interval(m_interface->kodiBase,
m_controlHandle, interval);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
/// @brief Sets the percent of the slider.
///
- /// @param[in] percent float - Percent value of slide
+ /// @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
+ /// @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)
@@ -220,17 +211,16 @@ public:
m_interface->kodi_gui->control_settings_slider->set_percentage(m_interface->kodiBase,
m_controlHandle, percent);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
/// @brief Returns a float of the percent of the slider.
///
- /// @return float - Percent of 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
+ /// @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
@@ -238,13 +228,12 @@ public:
return m_interface->kodi_gui->control_settings_slider->get_percentage(m_interface->kodiBase,
m_controlHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
+ //============================================================================
+ /// @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
+ /// 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.
@@ -252,11 +241,11 @@ public:
/// 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
+ /// @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
+ /// @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)
@@ -264,19 +253,18 @@ public:
m_interface->kodi_gui->control_settings_slider->set_float_range(m_interface->kodiBase,
m_controlHandle, start, end);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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
+ //============================================================================
+ /// @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
+ /// @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
+ /// @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)
@@ -284,33 +272,31 @@ public:
m_interface->kodi_gui->control_settings_slider->set_float_value(m_interface->kodiBase,
m_controlHandle, value);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSettingsSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSettingsSlider
/// @brief To get the current position as float value.
///
- /// @return The position as float
+ /// @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_controls_CSettingsSlider
- /// @brief To set the interval steps of slider, as default is it 0.1 If it
+ //============================================================================
+ /// @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.
+ /// @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
+ /// @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)
@@ -318,9 +304,11 @@ public:
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
index 715cc7da61..077def82fc 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Slider.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Slider.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/slider.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,35 +20,33 @@ namespace gui
namespace controls
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_controls_CSlider Control Slider
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CSlider }
-/// **Window control for moveable slider**
+//==============================================================================
+/// @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).
///
-/// 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.
+/// 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>"
+/// 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"
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
class ATTRIBUTE_HIDDEN CSlider : public CAddonGUIControlBase
{
public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
- /// @brief Construct a new control
+ //============================================================================
+ /// @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
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
CSlider(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -56,61 +56,56 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::controls::CSlider can't create control class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
- /// @brief Destructor
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Destructor.
///
~CSlider() override = default;
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
- /// @brief Set the control on window to visible
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
+ /// @brief Set the control on window to visible.
///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CSlider
- /// @brief Set's the control's enabled/disabled state
- ///
- /// @param[in] enabled If true enabled, otherwise disabled
+ /// @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_controls_CSlider
- /// @brief To reset slider on defaults
+ //============================================================================
+ /// @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_controls_CSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
/// @brief With GetDescription becomes a string value of position returned.
///
- /// @return Text string about current slider position
+ /// @return Text string about current slider position
///
/// The following are the text definition returned from this:
/// | Value | Without range selection | With range selection |
@@ -132,13 +127,12 @@ public:
}
return text;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
+ //============================================================================
+ /// @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
+ /// 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.
@@ -146,11 +140,11 @@ public:
/// 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
+ /// @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
+ /// @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)
@@ -158,18 +152,17 @@ public:
m_interface->kodi_gui->control_slider->set_int_range(m_interface->kodiBase, m_controlHandle,
start, end);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup CSlider
- /// @brief Set the slider position with the given integer value. The Range
- /// must be defined with a call from \ref SetIntRange before.
+ //============================================================================
+ /// @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
+ /// @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
+ /// @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)
@@ -177,17 +170,16 @@ public:
m_interface->kodi_gui->control_slider->set_int_value(m_interface->kodiBase, m_controlHandle,
value);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
/// @brief To get the current position as integer value.
///
- /// @return The position as integer
+ /// @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
+ /// @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
@@ -195,19 +187,18 @@ public:
return m_interface->kodi_gui->control_slider->get_int_value(m_interface->kodiBase,
m_controlHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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
+ //============================================================================
+ /// @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.
+ /// @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
+ /// @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)
@@ -215,17 +206,16 @@ public:
m_interface->kodi_gui->control_slider->set_int_interval(m_interface->kodiBase, m_controlHandle,
interval);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
/// @brief Sets the percent of the slider.
///
- /// @param[in] percent float - Percent value of slide
+ /// @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
+ /// @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)
@@ -233,17 +223,16 @@ public:
m_interface->kodi_gui->control_slider->set_percentage(m_interface->kodiBase, m_controlHandle,
percent);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
/// @brief Returns a float of the percent of the slider.
///
- /// @return float - Percent of 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
+ /// @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
@@ -251,13 +240,12 @@ public:
return m_interface->kodi_gui->control_slider->get_percentage(m_interface->kodiBase,
m_controlHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
+ //============================================================================
+ /// @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
+ /// 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.
@@ -265,11 +253,11 @@ public:
/// 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
+ /// @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
+ /// @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)
@@ -277,19 +265,18 @@ public:
m_interface->kodi_gui->control_slider->set_float_range(m_interface->kodiBase, m_controlHandle,
start, end);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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
+ //============================================================================
+ /// @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
+ /// @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
+ /// @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)
@@ -297,33 +284,31 @@ public:
m_interface->kodi_gui->control_slider->set_float_value(m_interface->kodiBase, m_controlHandle,
value);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CSlider
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSlider
/// @brief To get the current position as float value.
///
- /// @return The position as float
+ /// @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_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
+ //============================================================================
+ /// @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.
+ /// @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
+ /// @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)
@@ -331,9 +316,11 @@ public:
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
index db8d4913f7..6c552438d7 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Spin.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/Spin.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/spin.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -18,348 +20,397 @@ 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 ATTRIBUTE_HIDDEN CSpin : public CAddonGUIControlBase
+{
+public:
//============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Construct a new control.
///
- /// \defgroup cpp_kodi_gui_controls_CSpin Control Spin
- /// \ingroup cpp_kodi_gui
- /// @brief \cpp_class{ kodi::gui::controls::CSpin }
- /// **Window control used for cycling up/down controls**
- ///
- /// 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.
+ /// @param[in] window Related window control class
+ /// @param[in] controlId Used skin xml control id
///
- /// It has the header \ref Spin.h "#include <kodi/gui/controls/Spin.h>"
- /// be included to enjoy it.
+ 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.
///
- /// Here you find the needed skin part for a \ref Spin_Control "spin control"
+ ~CSpin() override = default;
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CSpin
+ /// @brief Set the control on window to visible.
///
- /// @note The call of the control is only possible from the corresponding
- /// window as its class and identification number is required.
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CSpin
- /// @anchor AddonGUISpinControlType
- /// @brief The values here defines the used value format for steps on
- /// spin control.
+ /// @param[in] enabled If true enabled, otherwise disabled
///
- typedef enum AddonGUISpinControlType
+ void SetEnabled(bool enabled)
{
- /// 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;
+ m_interface->kodi_gui->control_spin->set_enabled(m_interface->kodiBase, m_controlHandle,
+ enabled);
+ }
//----------------------------------------------------------------------------
- class ATTRIBUTE_HIDDEN CSpin : public CAddonGUIControlBase
+ //============================================================================
+ /// @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)
{
- public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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_controls_CSpin
- /// @brief Destructor
- ///
- ~CSpin() override = default;
- //--------------------------------------------------------------------------
-
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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_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_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());
- }
- //--------------------------------------------------------------------------
+ m_interface->kodi_gui->control_spin->set_text(m_interface->kodiBase, m_controlHandle,
+ text.c_str());
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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 reset spin control to defaults.
+ ///
+ void Reset()
+ {
+ m_interface->kodi_gui->control_spin->reset(m_interface->kodiBase, m_controlHandle);
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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 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_controls_CSpin
- /// @brief To add a label entry in spin defined with a value as string.
- ///
- /// Format must be set to 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 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_controls_CSpin
- /// @brief To add a label entry in spin defined with a value as integer.
- ///
- /// Format must be set to 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 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_controls_CSpin
- /// @brief To change the spin to position with them string as value.
- ///
- /// Format must be set to 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 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_controls_CSpin
- /// @brief To get the current spin control position with text string value.
- ///
- /// Format must be set to ADDON_SPIN_CONTROL_TYPE_TEXT to use this function.
- ///
- /// @return Currently selected string value
- ///
- std::string GetStringValue() const
+ //============================================================================
+ /// @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)
{
- 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;
+ if (std::strlen(ret))
+ value = ret;
+ m_interface->free_string(m_interface->kodiBase, ret);
}
- //--------------------------------------------------------------------------
+ return value;
+ }
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_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 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_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 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_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 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_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 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_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 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_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 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_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);
- }
- //--------------------------------------------------------------------------
- };
+ //============================================================================
+ /// @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
index b4e8ae0717..2634568e87 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/TextBox.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/controls/TextBox.h
@@ -8,9 +8,11 @@
#pragma once
-#include "../../AddonBase.h"
+#include "../../c-api/gui/controls/text_box.h"
#include "../Window.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -19,34 +21,33 @@ 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.
///
-/// \defgroup cpp_kodi_gui_controls_CTextBox Control Text Box
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::controls::CTextBox }
-/// **Used to show a multi-page piece of text**
-///
-/// 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 CDialogTextViewer.
+/// 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>"
+/// 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".
+/// 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
+/// @note The call of the control is only possible from the corresponding
/// window as its class and identification number is required.
///
class ATTRIBUTE_HIDDEN CTextBox : public CAddonGUIControlBase
{
public:
//==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief Construct a new control.
///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
- /// @brief Construct a new control
- ///
- /// @param[in] window related window control class
- /// @param[in] controlId Used skin xml control id
+ /// @param[in] window related window control class
+ /// @param[in] controlId Used skin xml control id
///
CTextBox(CWindow* window, int controlId) : CAddonGUIControlBase(window)
{
@@ -59,19 +60,17 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
- /// @brief Destructor
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
- /// @brief Set the control on window to visible
- ///
- /// @param[in] visible If true visible, otherwise hidden
+ /// @param[in] visible If true visible, otherwise hidden
///
void SetVisible(bool visible)
{
@@ -81,19 +80,17 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
- /// @brief To reset box an remove all the text
+ /// @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.
///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
- /// @brief To set the text on box
- ///
- /// @param[in] text Text to show
+ /// @param[in] text Text to show
///
void SetText(const std::string& text)
{
@@ -103,11 +100,10 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief Get the used text from control.
///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
- /// @brief Get the used text from control
- ///
- /// @return Text shown
+ /// @return Text shown
///
std::string GetText() const
{
@@ -125,11 +121,10 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
+ /// @brief To scroll text on other position.
///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
- /// @brief To scroll text on other position
- ///
- /// @param[in] position The line position to scroll to
+ /// @param[in] position The line position to scroll to
///
void Scroll(unsigned int position)
{
@@ -139,8 +134,7 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_controls_CTextBox
+ /// @ingroup cpp_kodi_gui_windows_controls_CTextBox
/// @brief To set automatic scrolling of textbox
///
/// Specifies the timing and conditions of any autoscrolling this textbox
@@ -150,10 +144,10 @@ public:
/// 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
+ /// @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)
{
@@ -166,3 +160,5 @@ public:
} /* namespace controls */
} /* namespace gui */
} /* namespace kodi */
+
+#endif /* __cplusplus */
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/gui/definitions.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/definitions.h
deleted file mode 100644
index 4eb64c7a09..0000000000
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/definitions.h
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * 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 <string>
-#include <time.h>
-
-/*
- * Internal Structures to have "C"-Style data transfer
- */
-extern "C"
-{
-
-typedef struct AddonToKodiFuncTable_kodi_gui_general
-{
- void (*lock)();
- void (*unlock)();
- int (*get_screen_height)(void* kodiBase);
- int (*get_screen_width)(void* kodiBase);
- int (*get_video_resolution)(void* kodiBase);
- int (*get_current_window_dialog_id)(void* kodiBase);
- int (*get_current_window_id)(void* kodiBase);
- void* (*get_hw_context)(void* kodiBase);
-} AddonToKodiFuncTable_kodi_gui_general;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_button
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_enabled)(void* kodiBase, void* handle, bool enabled);
- void (*set_label)(void* kodiBase, void* handle, const char* label);
- char* (*get_label)(void* kodiBase, void* handle);
- void (*set_label2)(void* kodiBase, void* handle, const char *label);
- char* (*get_label2)(void* kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_control_button;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_edit
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_enabled)(void* kodiBase, void* handle, bool enabled);
- void (*set_label)(void* kodiBase, void* handle, const char* label);
- char* (*get_label)(void* kodiBase, void* handle);
- void (*set_text)(void* kodiBase, void* handle, const char* text);
- char* (*get_text)(void* kodiBase, void* handle);
- void (*set_cursor_position)(void* kodiBase, void* handle, unsigned int position);
- unsigned int (*get_cursor_position)(void* kodiBase, void* handle);
- void (*set_input_type)(void* kodiBase, void* handle, int type, const char* heading);
-} AddonToKodiFuncTable_kodi_gui_control_edit;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_fade_label
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*add_label)(void* kodiBase, void* handle, const char* text);
- char* (*get_label)(void* kodiBase, void* handle);
- void (*set_scrolling)(void* kodiBase, void* handle, bool scroll);
- void (*reset)(void* kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_control_fade_label;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_image
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_filename)(void* kodiBase, void* handle, const char* filename, bool use_cache);
- void (*set_color_diffuse)(void* kodiBase, void* handle, uint32_t color_diffuse);
-} AddonToKodiFuncTable_kodi_gui_control_image;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_label
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_label)(void* kodiBase, void* handle, const char* text);
- char* (*get_label)(void* kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_control_label;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_progress
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_percentage)(void* kodiBase, void* handle, float percent);
- float (*get_percentage)(void* kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_control_progress;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_radio_button
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_enabled)(void* kodiBase, void* handle, bool enabled);
- void (*set_label)(void* kodiBase, void* handle, const char* text);
- char* (*get_label)(void* kodiBase, void* handle);
- void (*set_selected)(void* kodiBase, void* handle, bool selected);
- bool (*is_selected)(void* kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_control_radio_button;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_rendering
-{
- void (*set_callbacks)(void* kodiBase, void* handle, void* clienthandle,
- bool (*createCB)(void*,int,int,int,int,void*),
- void (*renderCB)(void*),
- void (*stopCB)(void*),
- bool (*dirtyCB)(void*));
- void (*destroy)(void *kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_control_rendering;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_settings_slider
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_enabled)(void* kodiBase, void* handle, bool enabled);
- void (*set_text)(void* kodiBase, void* handle, const char* label);
- void (*reset)(void* kodiBase, void* handle);
- void (*set_int_range)(void* kodiBase, void* handle, int start, int end);
- void (*set_int_value)(void* kodiBase, void* handle, int value);
- int (*get_int_value)(void* kodiBase, void* handle);
- void (*set_int_interval)(void* kodiBase, void* handle, int interval);
- void (*set_percentage)(void* kodiBase, void* handle, float percent);
- float (*get_percentage)(void* kodiBase, void* handle);
- void (*set_float_range)(void* kodiBase, void* handle, float start, float end);
- void (*set_float_value)(void* kodiBase, void* handle, float value);
- float (*get_float_value)(void* kodiBase, void* handle);
- void (*set_float_interval)(void* kodiBase, void* handle, float interval);
-} AddonToKodiFuncTable_kodi_gui_control_settings_slider;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_slider
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_enabled)(void* kodiBase, void* handle, bool enabled);
- void (*reset)(void* kodiBase, void* handle);
- char* (*get_description)(void* kodiBase, void* handle);
- void (*set_int_range)(void* kodiBase, void* handle, int start, int end);
- void (*set_int_value)(void* kodiBase, void* handle, int value);
- int (*get_int_value)(void* kodiBase, void* handle);
- void (*set_int_interval)(void* kodiBase, void* handle, int interval);
- void (*set_percentage)(void* kodiBase, void* handle, float percent);
- float (*get_percentage)(void* kodiBase, void* handle);
- void (*set_float_range)(void* kodiBase, void* handle, float start, float end);
- void (*set_float_value)(void* kodiBase, void* handle, float value);
- float (*get_float_value)(void* kodiBase, void* handle);
- void (*set_float_interval)(void* kodiBase, void* handle, float interval);
-} AddonToKodiFuncTable_kodi_gui_control_slider;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_spin
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*set_enabled)(void* kodiBase, void* handle, bool enabled);
- void (*set_text)(void* kodiBase, void* handle, const char* text);
- void (*reset)(void* kodiBase, void* handle);
- void (*set_type)(void* kodiBase, void* handle, int type);
- void (*add_string_label)(void* kodiBase, void* handle, const char* label, const char* value);
- void (*set_string_value)(void* kodiBase, void* handle, const char* value);
- char* (*get_string_value)(void* kodiBase, void* handle);
- void (*add_int_label)(void* kodiBase, void* handle, const char* label, int value);
- void (*set_int_range)(void* kodiBase, void* handle, int start, int end);
- void (*set_int_value)(void* kodiBase, void* handle, int value);
- int (*get_int_value)(void* kodiBase, void* handle);
- void (*set_float_range)(void* kodiBase, void* handle, float start, float end);
- void (*set_float_value)(void* kodiBase, void* handle, float value);
- float (*get_float_value)(void* kodiBase, void* handle);
- void (*set_float_interval)(void* kodiBase, void* handle, float interval);
-} AddonToKodiFuncTable_kodi_gui_control_spin;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_control_text_box
-{
- void (*set_visible)(void* kodiBase, void* handle, bool visible);
- void (*reset)(void* kodiBase, void* handle);
- void (*set_text)(void* kodiBase, void* handle, const char* text);
- char* (*get_text)(void* kodiBase, void* handle);
- void (*scroll)(void* kodiBase, void* handle, unsigned int scroll);
- void (*set_auto_scrolling)(void* kodiBase, void* handle, int delay, int time, int repeat);
-} AddonToKodiFuncTable_kodi_gui_control_text_box;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogContextMenu
-{
- int (*open)(void* kodiBase, const char *heading, const char *entries[], unsigned int size);
-} AddonToKodiFuncTable_kodi_gui_dialogContextMenu;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress
-{
- void* (*new_dialog)(void* kodiBase, const char *title);
- void (*delete_dialog)(void* kodiBase, void* handle);
- char* (*get_title)(void* kodiBase, void* handle);
- void (*set_title)(void* kodiBase, void* handle, const char *title);
- char* (*get_text)(void* kodiBase, void* handle);
- void (*set_text)(void* kodiBase, void* handle, const char *text);
- bool (*is_finished)(void* kodiBase, void* handle);
- void (*mark_finished)(void* kodiBase, void* handle);
- float (*get_percentage)(void* kodiBase, void* handle);
- void (*set_percentage)(void* kodiBase, void* handle, float percentage);
- void (*set_progress)(void* kodiBase, void* handle, int currentItem, int itemCount);
-} AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogFileBrowser
-{
- bool (*show_and_get_directory)(void* kodiBase, const char* shares, const char* heading, const char* path_in, char** path_out, bool writeOnly);
- bool (*show_and_get_file)(void* 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)(void* 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)(void* 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)(void* kodiBase, const char* path_in, char** path_out, bool allow_network_shares, const char* additional_share, const char* type);
- bool (*show_and_get_image)(void* kodiBase, const char* shares, const char* heading, const char* path_in, char** path_out);
- bool (*show_and_get_image_list)(void* kodiBase, const char* shares, const char* heading, char*** file_list, unsigned int* entries);
- void (*clear_file_list)(void* kodiBase, char*** file_list, unsigned int entries);
-} AddonToKodiFuncTable_kodi_gui_dialogFileBrowser;
-
-// typedef void (*char_callback_t) (CGUIKeyboard *ref, const std::string &typedString);
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogKeyboard
-{
- bool (*show_and_get_input_with_head)(void* 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)(void* 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)(void* 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)(void* kodiBase, const char* password_in, char** password_out, unsigned int auto_close_ms);
- bool (*show_and_verify_new_password_with_head)(void* kodiBase, char** password_out, const char* heading, bool allow_empty_result, unsigned int auto_close_ms);
- bool (*show_and_verify_new_password)(void* kodiBase, char** password_out, unsigned int auto_close_ms);
- int (*show_and_verify_password)(void* kodiBase, const char* password_in, char** password_out, const char* heading, int retries, unsigned int auto_close_ms);
- bool (*show_and_get_filter)(void* kodiBase, const char* text_in, char** text_out, bool searching, unsigned int auto_close_ms);
- bool (*send_text_to_active_keyboard)(void* kodiBase, const char* text, bool close_keyboard);
- bool (*is_keyboard_activated)(void* kodiBase);
-} AddonToKodiFuncTable_kodi_gui_dialogKeyboard;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogNumeric
-{
- bool (*show_and_verify_new_password)(void* kodiBase, char** password);
- int (*show_and_verify_password)(void* kodiBase, const char* password, const char *heading, int retries);
- bool (*show_and_verify_input)(void* kodiBase, const char* verify_in, char** verify_out, const char* heading, bool verify_input);
- bool (*show_and_get_time)(void* kodiBase, tm *time, const char *heading);
- bool (*show_and_get_date)(void* kodiBase, tm *date, const char *heading);
- bool (*show_and_get_ip_address)(void* kodiBase, const char* ip_address_in, char** ip_address_out, const char *heading);
- bool (*show_and_get_number)(void* kodiBase, const char* input_in, char** input_out, const char *heading, unsigned int auto_close_ms);
- bool (*show_and_get_seconds)(void* kodiBase, const char* time_in, char** time_out, const char *heading);
-} AddonToKodiFuncTable_kodi_gui_dialogNumeric;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogOK
-{
- void (*show_and_get_input_single_text)(void* kodiBase, const char *heading, const char *text);
- void (*show_and_get_input_line_text)(void* kodiBase, const char *heading, const char *line0, const char *line1, const char *line2);
-} AddonToKodiFuncTable_kodi_gui_dialogOK;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogProgress
-{
- void* (*new_dialog)(void* kodiBase);
- void (*delete_dialog)(void* kodiBase, void* handle);
- void (*open)(void* kodiBase, void* handle);
- void (*set_heading)(void* kodiBase, void* handle, const char* heading);
- void (*set_line)(void* kodiBase, void* handle, unsigned int lineNo, const char* line);
- void (*set_can_cancel)(void* kodiBase, void* handle, bool canCancel);
- bool (*is_canceled)(void* kodiBase, void* handle);
- void (*set_percentage)(void* kodiBase, void* handle, int percentage);
- int (*get_percentage)(void* kodiBase, void* handle);
- void (*show_progress_bar)(void* kodiBase, void* handle, bool pnOff);
- void (*set_progress_max)(void* kodiBase, void* handle, int max);
- void (*set_progress_advance)(void* kodiBase, void* handle, int nSteps);
- bool (*abort)(void* kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_dialogProgress;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogSelect
-{
- int (*open)(void* kodiBase, const char *heading, const char *entries[], unsigned int size, int selected, unsigned int autoclose);
- bool (*open_multi_select)(void* kodiBase, const char* heading, const char* entryIDs[], const char* entryNames[],
- bool entriesSelected[], unsigned int size, unsigned int autoclose);
-} AddonToKodiFuncTable_kodi_gui_dialogSelect;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogTextViewer
-{
- void (*open)(void* kodiBase, const char *heading, const char *text);
-} AddonToKodiFuncTable_kodi_gui_dialogTextViewer;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_dialogYesNo
-{
- bool (*show_and_get_input_single_text)(void* kodiBase, const char *heading, const char *text, bool *canceled, const char *noLabel, const char *yesLabel);
- bool (*show_and_get_input_line_text)(void* 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)(void* 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;
-
-typedef struct AddonToKodiFuncTable_kodi_gui_listItem
-{
- void* (*create)(void* kodiBase, const char* label, const char* label2, const char* icon_image, const char* path);
- void (*destroy)(void* kodiBase, void* handle);
- char* (*get_label)(void* kodiBase, void* handle);
- void (*set_label)(void* kodiBase, void* handle, const char* label);
- char* (*get_label2)(void* kodiBase, void* handle);
- void (*set_label2)(void* kodiBase, void* handle, const char* label);
- char* (*get_art)(void* kodiBase, void* handle, const char* type);
- void (*set_art)(void* kodiBase, void* handle, const char* type, const char* image);
- char* (*get_path)(void* kodiBase, void* handle);
- void (*set_path)(void* kodiBase, void* handle, const char* path);
- char* (*get_property)(void* kodiBase, void* handle, const char* key);
- void (*set_property)(void* kodiBase, void* handle, const char* key, const char* value);
- void (*select)(void* kodiBase, void* handle, bool select);
- bool (*is_selected)(void* kodiBase, void* handle);
-} AddonToKodiFuncTable_kodi_gui_listItem;
-
-#define ADDON_MAX_CONTEXT_ENTRIES 20
-#define ADDON_MAX_CONTEXT_ENTRY_NAME_LENGTH 80
-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 */
- void* (*create)(void* kodiBase, const char* xml_filename, const char* default_skin, bool as_dialog, bool is_media);
- void (*destroy)(void* kodiBase, void* handle);
- void (*set_callbacks)(void* kodiBase, void* handle, void* clienthandle,
- bool (*CBInit)(void*),
- bool (*CBFocus)(void*, int),
- bool (*CBClick)(void*, int),
- bool (*CBOnAction)(void*, int, uint32_t, wchar_t),
- void (*CBGetContextButtons)(void*, int, gui_context_menu_pair*, unsigned int*),
- bool (*CBOnContextButton)(void*, int, unsigned int));
- bool (*show)(void* kodiBase, void* handle);
- bool (*close)(void* kodiBase, void* handle);
- bool (*do_modal)(void* kodiBase, void* handle);
-
- /* Window control functions */
- bool (*set_focus_id)(void* kodiBase, void* handle, int control_id);
- int (*get_focus_id)(void* kodiBase, void* handle);
- void (*set_control_label)(void* kodiBase, void* handle, int control_id, const char* label);
- void (*set_control_visible)(void* kodiBase, void* handle, int control_id, bool visible);
- void (*set_control_selected)(void* kodiBase, void* handle, int control_id, bool selected);
-
- /* Window property functions */
- void (*set_property)(void* kodiBase, void* handle, const char* key, const char* value);
- void (*set_property_int)(void* kodiBase, void* handle, const char* key, int value);
- void (*set_property_bool)(void* kodiBase, void* handle, const char* key, bool value);
- void (*set_property_double)(void* kodiBase, void* handle, const char* key, double value);
- char* (*get_property)(void* kodiBase, void* handle, const char* key);
- int (*get_property_int)(void* kodiBase, void* handle, const char* key);
- bool (*get_property_bool)(void* kodiBase, void* handle, const char* key);
- double (*get_property_double)(void* kodiBase, void* handle, const char* key);
- void (*clear_properties)(void* kodiBase, void* handle);
- void (*clear_property)(void* kodiBase, void* handle, const char* key);
-
- /* List item functions */
- void (*clear_item_list)(void* kodiBase, void* handle);
- void (*add_list_item)(void* kodiBase, void* handle, void* item, int list_position);
- void (*remove_list_item_from_position)(void* kodiBase, void* handle, int list_position);
- void (*remove_list_item)(void* kodiBase, void* handle, void* item);
- void* (*get_list_item)(void* kodiBase, void* handle, int list_position);
- void (*set_current_list_position)(void* kodiBase, void* handle, int list_position);
- int (*get_current_list_position)(void* kodiBase, void* handle);
- int (*get_list_size)(void* kodiBase, void* handle);
- void (*set_container_property)(void* kodiBase, void* handle, const char* key, const char* value);
- void (*set_container_content)(void* kodiBase, void* handle, const char* value);
- int (*get_current_container_id)(void* kodiBase, void* handle);
-
- /* Various functions */
- void (*mark_dirty_region)(void* kodiBase, void* handle);
-
- /* GUI control access functions */
- void* (*get_control_button)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_edit)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_fade_label)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_image)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_label)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_progress)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_radio_button)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_render_addon)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_settings_slider)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_slider)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_spin)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_text_box)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy1)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy2)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy3)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy4)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy5)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy6)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy7)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy8)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy9)(void* kodiBase, void* handle, int control_id);
- void* (*get_control_dummy10)(void* kodiBase, void* handle, int control_id); /* This and above used to add new get_control_* functions */
-} AddonToKodiFuncTable_kodi_gui_window;
-
-typedef struct AddonToKodiFuncTable_kodi_gui
-{
- AddonToKodiFuncTable_kodi_gui_general* general;
- AddonToKodiFuncTable_kodi_gui_control_button* control_button;
- AddonToKodiFuncTable_kodi_gui_control_edit* control_edit;
- AddonToKodiFuncTable_kodi_gui_control_fade_label* control_fade_label;
- AddonToKodiFuncTable_kodi_gui_control_label* control_label;
- AddonToKodiFuncTable_kodi_gui_control_image* control_image;
- AddonToKodiFuncTable_kodi_gui_control_progress* control_progress;
- AddonToKodiFuncTable_kodi_gui_control_radio_button* control_radio_button;
- AddonToKodiFuncTable_kodi_gui_control_rendering* control_rendering;
- AddonToKodiFuncTable_kodi_gui_control_settings_slider* control_settings_slider;
- AddonToKodiFuncTable_kodi_gui_control_slider* control_slider;
- AddonToKodiFuncTable_kodi_gui_control_spin* control_spin;
- AddonToKodiFuncTable_kodi_gui_control_text_box* control_text_box;
- void* control_dummy1;
- void* control_dummy2;
- void* control_dummy3;
- void* control_dummy4;
- void* control_dummy5;
- void* control_dummy6;
- void* control_dummy7;
- void* control_dummy8;
- void* control_dummy9;
- void* control_dummy10; /* This and above used to add new controls */
- AddonToKodiFuncTable_kodi_gui_dialogContextMenu* dialogContextMenu;
- AddonToKodiFuncTable_kodi_gui_dialogExtendedProgress* dialogExtendedProgress;
- AddonToKodiFuncTable_kodi_gui_dialogFileBrowser* dialogFileBrowser;
- AddonToKodiFuncTable_kodi_gui_dialogKeyboard* dialogKeyboard;
- AddonToKodiFuncTable_kodi_gui_dialogNumeric* dialogNumeric;
- AddonToKodiFuncTable_kodi_gui_dialogOK* dialogOK;
- AddonToKodiFuncTable_kodi_gui_dialogProgress* dialogProgress;
- AddonToKodiFuncTable_kodi_gui_dialogSelect* dialogSelect;
- AddonToKodiFuncTable_kodi_gui_dialogTextViewer* dialogTextViewer;
- AddonToKodiFuncTable_kodi_gui_dialogYesNo* dialogYesNo;
- void* dialog_dummy1;
- void* dialog_dummy2;
- void* dialog_dummy3;
- void* dialog_dummy4;
- void* dialog_dummy5;
- void* dialog_dummy6;
- void* dialog_dummy7;
- void* dialog_dummy8;
- void* dialog_dummy9;
- void* dialog_dummy10; /* This and above used to add new dialogs */
- AddonToKodiFuncTable_kodi_gui_listItem* listItem;
- AddonToKodiFuncTable_kodi_gui_window* window;
-} AddonToKodiFuncTable_kodi_gui;
-
-} /* extern "C" */
-
-//============================================================================
-///
-/// \ingroup cpp_kodi_gui_CControlRendering_Defs cpp_kodi_gui_CWindow_Defs
-/// @{
-/// @brief Handle to use as independent pointer for GUI
-typedef void* GUIHANDLE;
-/// @}
-//----------------------------------------------------------------------------
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
index d54503006a..b576b9a9fa 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ContextMenu.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ContextMenu.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/context_menu.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,168 +20,167 @@ namespace gui
namespace dialogs
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_ContextMenu Dialog Context Menu
- /// \ingroup cpp_kodi_gui
- /// @brief \cpp_namespace{ kodi::gui::dialogs::ContextMenu }
- /// **Context menu dialog**
- ///
- /// 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
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN 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)
{
- //==========================================================================
- ///
- /// \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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(
- CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size);
- free(cEntries);
- return ret;
- }
- //--------------------------------------------------------------------------
+ cEntries[i] = entries[i].c_str();
+ }
+ int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(
+ CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size);
+ free(cEntries);
+ return ret;
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_ContextMenu
- /// @brief Show a context menu dialog about given parts.
- ///
- /// @param[in] heading Dialog heading name
- /// @param[in] entries String list about entries
- /// @return The selected entry, if return <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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size);
- free(cEntries);
- return ret;
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_ContextMenu
+/// @brief Show a context menu dialog about given parts.
+///
+/// @param[in] heading Dialog heading name
+/// @param[in] entries String list about entries
+/// @return The selected entry, if return <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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(
+ CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size);
+ free(cEntries);
+ return ret;
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_ContextMenu
- /// @brief Show a context menu dialog about given parts.
- ///
- /// @param[in] heading Dialog heading name
- /// @param[in] entries String list about entries
- /// @return The selected entry, if return <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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size);
- free(cEntries);
- return ret;
- }
- //--------------------------------------------------------------------------
- };
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_ContextMenu
+/// @brief Show a context menu dialog about given parts.
+///
+/// @param[in] heading Dialog heading name
+/// @param[in] entries String list about entries
+/// @return The selected entry, if return <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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(
+ CAddonBase::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
index 5a49b70b85..c650483f1c 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/ExtendedProgress.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/extended_progress.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,14 +20,13 @@ namespace gui
namespace dialogs
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_dialogs_CExtendedProgress Dialog Extended Progress
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::dialogs::ExtendedProgress }
+//==============================================================================
+/// @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>"
+/// The with @ref ExtendedProgress.h "#include <kodi/gui/dialogs/ExtendedProgress.h>"
/// given class are basically used to create Kodi's extended progress.
///
///
@@ -57,12 +58,11 @@ namespace dialogs
class ATTRIBUTE_HIDDEN CExtendedProgress
{
public:
- //==========================================================================
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// Construct a new dialog.
///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// Construct a new dialog
- ///
- /// @param[in] title Title string
+ /// @param[in] title [opt] Title string
///
explicit CExtendedProgress(const std::string& title = "")
{
@@ -73,12 +73,11 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::CDialogExtendedProgress can't create window class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// Destructor
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// Destructor.
///
~CExtendedProgress()
{
@@ -87,12 +86,11 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->delete_dialog(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief Get the used title
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Get the used title.
///
/// @return Title string
///
@@ -111,14 +109,13 @@ public:
}
return text;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief To set the title of dialog
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To set the title of dialog.
///
- /// @param[in] title Title string
+ /// @param[in] title Title string
///
void SetTitle(const std::string& title)
{
@@ -126,12 +123,11 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_title(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, title.c_str());
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief Get the used text information string
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Get the used text information string.
///
/// @return Text string
///
@@ -150,14 +146,13 @@ public:
}
return text;
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To set the used text information string.
///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief To set the used text information string
- ///
- /// @param[in] text information text to set
+ /// @param[in] text Information text to set
///
void SetText(const std::string& text)
{
@@ -165,12 +160,11 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_text(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, text.c_str());
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief To ask dialog is finished
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To ask dialog is finished.
///
/// @return True if on end
///
@@ -180,12 +174,11 @@ public:
return CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->is_finished(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief Mark progress finished
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Mark progress finished.
///
void MarkFinished()
{
@@ -193,12 +186,11 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->mark_finished(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief Get the current progress position as percent
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief Get the current progress position as percent.
///
/// @return Position
///
@@ -208,14 +200,13 @@ public:
return CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->get_percentage(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CExtendedProgress
+ /// @brief To set the current progress position as percent.
///
- /// \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
+ /// @param[in] percentage Position to use from 0.0 to 100.0
///
void SetPercentage(float percentage)
{
@@ -223,15 +214,14 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_percentage(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, percentage);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CExtendedProgress
- /// @brief To set progress position with predefined places
+ //============================================================================
+ /// @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
+ /// @param[in] currentItem Place position to use
+ /// @param[in] itemCount Amount of used places
///
void SetProgress(int currentItem, int itemCount)
{
@@ -239,12 +229,14 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogExtendedProgress->set_progress(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, currentItem, itemCount);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
private:
- void* m_DialogHandle;
+ 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
index 90da0635cf..244c76cc9f 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/FileBrowser.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/FileBrowser.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/filebrowser.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,293 +20,283 @@ namespace gui
namespace dialogs
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_FileBrowser Dialog File Browser
- /// \ingroup cpp_kodi_gui
- /// @brief \cpp_namespace{ kodi::gui::dialogs::FileBrowser }
- /// **File browser dialog**
- ///
- /// 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
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndGetDirectory(const std::string& shares,
+ const std::string& heading,
+ std::string& path,
+ bool writeOnly = false)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_directory(
+ CAddonBase::m_interface->toKodi->kodiBase, shares.c_str(), heading.c_str(), path.c_str(),
+ &retString, writeOnly);
+ if (retString != nullptr)
{
- //==========================================================================
- ///
- /// \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 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 ATTRIBUTE_HIDDEN ShowAndGetDirectory(const std::string& shares,
- const std::string& heading,
- std::string& path,
- bool writeOnly = false)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_directory(
- CAddonBase::m_interface->toKodi->kodiBase, shares.c_str(), heading.c_str(), path.c_str(),
- &retString, writeOnly);
- if (retString != nullptr)
- {
- if (std::strlen(retString))
- path = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
- retString);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+ if (std::strlen(retString))
+ path = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 If set show thumbs if possible on dialog.
- /// @param[in] useFileDirectories If set also packages (e.g. *.zip) are
- /// handled as directories.
- /// @return False if selection becomes canceled.
- ///
- inline bool ATTRIBUTE_HIDDEN ShowAndGetFile(const std::string& shares,
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file(
+ CAddonBase::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;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN 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 =
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_from_dir(
+ CAddonBase::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;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetFileList(const std::string& shares,
const std::string& mask,
const std::string& heading,
- std::string& path,
+ std::vector<std::string>& fileList,
bool useThumbs = false,
bool useFileDirectories = false)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file(CAddonBase::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;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 If set show thumbs if possible on dialog.
- /// @param[in] useFileDirectories If set also packages (e.g. *.zip) are
- /// handled as directories.
- /// @param[in] singleList
- /// @return False if selection becomes canceled.
- ///
- inline bool ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_from_dir(CAddonBase::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;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+{
+ using namespace ::kodi::addon;
+ char** list = nullptr;
+ unsigned int listSize = 0;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_list(
+ CAddonBase::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]);
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->clear_file_list(
+ CAddonBase::m_interface->toKodi->kodiBase, &list, listSize);
+ }
+ 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 If set show thumbs if possible on dialog.
- /// @param[in] useFileDirectories If set also packages (e.g. *.zip) are
- /// handled as directories.
- /// @return False if selection becomes canceled.
- ///
- inline bool ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_file_list(CAddonBase::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]);
- CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->clear_file_list(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetSource(std::string& path,
+ bool allowNetworkShares,
+ const std::string& additionalShare = "",
+ const std::string& type = "")
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_source(
+ CAddonBase::m_interface->toKodi->kodiBase, path.c_str(), &retString, allowNetworkShares,
+ additionalShare.c_str(), type.c_str());
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ path = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
+ retString);
+ }
+ 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 With additionalShare becomes the available
- /// start folders be set (optional).
- /// @param[in] type
- /// @return False if selection becomes canceled.
- ///
- inline bool ATTRIBUTE_HIDDEN ShowAndGetSource(std::string& path,
- bool allowNetworkShares,
- const std::string& additionalShare = "",
- const std::string& type = "")
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_source(CAddonBase::m_interface->toKodi->kodiBase, path.c_str(), &retString,
- allowNetworkShares, additionalShare.c_str(), type.c_str());
- if (retString != nullptr)
- {
- if (std::strlen(retString))
- path = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetImage(const std::string& shares,
+ const std::string& heading,
+ std::string& path)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image(
+ CAddonBase::m_interface->toKodi->kodiBase, shares.c_str(), heading.c_str(), path.c_str(),
+ &retString);
+ if (retString != nullptr)
+ {
+ if (std::strlen(retString))
+ path = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetImage(const std::string& shares,
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndGetImageList(const std::string& shares,
const std::string& heading,
- std::string& path)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image(CAddonBase::m_interface->toKodi->kodiBase,
- shares.c_str(), heading.c_str(), path.c_str(), &retString);
- if (retString != nullptr)
- {
- if (std::strlen(retString))
- path = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image_list(CAddonBase::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]);
- CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->clear_file_list(CAddonBase::m_interface->toKodi->kodiBase, &list, listSize);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
- };
+ std::vector<std::string>& file_list)
+{
+ using namespace ::kodi::addon;
+ char** list = nullptr;
+ unsigned int listSize = 0;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->show_and_get_image_list(
+ CAddonBase::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]);
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogFileBrowser->clear_file_list(
+ CAddonBase::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
index 843bdfa2d7..710b7dd563 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Keyboard.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Keyboard.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/keyboard.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,405 +20,385 @@ namespace gui
namespace dialogs
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_Keyboard Dialog Keyboard
- /// \ingroup cpp_kodi_gui
- /// @brief \cpp_namespace{ kodi::gui::dialogs::Keyboard }
- /// **Keyboard dialogs**
- ///
- /// 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
+//================================================================================
+/// @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 ATTRIBUTE_HIDDEN 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 =
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input_with_head(
+ CAddonBase::m_interface->toKodi->kodiBase, text.c_str(), &retString, heading.c_str(),
+ allowEmptyResult, hiddenInput, autoCloseMs);
+ if (retString != nullptr)
{
- //==========================================================================
- ///
- /// \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 The inserted input is not shown as text.
- /// @param[in] autoCloseMs 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 ATTRIBUTE_HIDDEN 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 =
- CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input_with_head(
- CAddonBase::m_interface->toKodi->kodiBase, text.c_str(), &retString, heading.c_str(),
- allowEmptyResult, hiddenInput, autoCloseMs);
- if (retString != nullptr)
- {
- text = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 ATTRIBUTE_HIDDEN ShowAndGetInput(std::string& text,
- bool allowEmptyResult,
- unsigned int autoCloseMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input(CAddonBase::m_interface->toKodi->kodiBase,
- text.c_str(), &retString,
- allowEmptyResult, autoCloseMs);
- if (retString != nullptr)
- {
- text = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+ text = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 ATTRIBUTE_HIDDEN ShowAndGetNewPassword(std::string& newPassword,
- const std::string& heading,
- bool allowEmptyResult,
- unsigned int autoCloseMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password_with_head(CAddonBase::m_interface->toKodi->kodiBase,
- newPassword.c_str(), &retString, heading.c_str(),
- allowEmptyResult, autoCloseMs);
- if (retString != nullptr)
- {
- newPassword = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 ATTRIBUTE_HIDDEN ShowAndGetNewPassword(std::string& newPassword,
- unsigned int autoCloseMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password(CAddonBase::m_interface->toKodi->kodiBase,
- newPassword.c_str(), &retString, autoCloseMs);
- if (retString != nullptr)
- {
- newPassword = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetInput(std::string& text,
+ bool allowEmptyResult,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_input(
+ CAddonBase::m_interface->toKodi->kodiBase, text.c_str(), &retString, allowEmptyResult,
+ autoCloseMs);
+ if (retString != nullptr)
+ {
+ text = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 successfull 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 ATTRIBUTE_HIDDEN ShowAndVerifyNewPassword(std::string& newPassword,
- const std::string& heading,
- bool allowEmptyResult,
- unsigned int autoCloseMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password_with_head(CAddonBase::m_interface->toKodi->kodiBase,
- &retString, heading.c_str(), allowEmptyResult,
- autoCloseMs);
- if (retString != nullptr)
- {
- newPassword = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetNewPassword(std::string& newPassword,
+ const std::string& heading,
+ bool allowEmptyResult,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard
+ ->show_and_get_new_password_with_head(
+ CAddonBase::m_interface->toKodi->kodiBase, newPassword.c_str(), &retString,
+ heading.c_str(), allowEmptyResult, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 ATTRIBUTE_HIDDEN ShowAndVerifyNewPassword(std::string& newPassword,
- unsigned int autoCloseMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password(CAddonBase::m_interface->toKodi->kodiBase,
- &retString, autoCloseMs);
- if (retString != nullptr)
- {
- newPassword = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetNewPassword(std::string& newPassword,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_new_password(
+ CAddonBase::m_interface->toKodi->kodiBase, newPassword.c_str(), &retString, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 ATTRIBUTE_HIDDEN ShowAndVerifyPassword(std::string& password,
+//==============================================================================
+/// @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 successfull 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 ATTRIBUTE_HIDDEN ShowAndVerifyNewPassword(std::string& newPassword,
const std::string& heading,
- int retries,
+ bool allowEmptyResult,
unsigned int autoCloseMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_password(CAddonBase::m_interface->toKodi->kodiBase,
- password.c_str(), &retString, heading.c_str(),
- retries, autoCloseMs);
- if (retString != nullptr)
- {
- password = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard
+ ->show_and_verify_new_password_with_head(CAddonBase::m_interface->toKodi->kodiBase,
+ &retString, heading.c_str(),
+ allowEmptyResult, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 ATTRIBUTE_HIDDEN ShowAndGetFilter(std::string& text,
- bool searching,
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndVerifyNewPassword(std::string& newPassword,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret =
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_new_password(
+ CAddonBase::m_interface->toKodi->kodiBase, &retString, autoCloseMs);
+ if (retString != nullptr)
+ {
+ newPassword = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndVerifyPassword(std::string& password,
+ const std::string& heading,
+ int retries,
unsigned int autoCloseMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_filter(CAddonBase::m_interface->toKodi->kodiBase,
- text.c_str(), &retString, searching, autoCloseMs);
- if (retString != nullptr)
- {
- text = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_verify_password(
+ CAddonBase::m_interface->toKodi->kodiBase, password.c_str(), &retString, heading.c_str(),
+ retries, autoCloseMs);
+ if (retString != nullptr)
+ {
+ password = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 The open dialog is if also closed on 'true'.
- /// @return true if successful done, false if
- /// unsuccessful or keyboard not present.
- ///
- inline bool ATTRIBUTE_HIDDEN SendTextToActiveKeyboard(const std::string& text,
- bool closeKeyboard = false)
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->send_text_to_active_keyboard(CAddonBase::m_interface->toKodi->kodiBase,
- text.c_str(), closeKeyboard);
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndGetFilter(std::string& text,
+ bool searching,
+ unsigned int autoCloseMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->show_and_get_filter(
+ CAddonBase::m_interface->toKodi->kodiBase, text.c_str(), &retString, searching, autoCloseMs);
+ if (retString != nullptr)
+ {
+ text = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN SendTextToActiveKeyboard(const std::string& text,
+ bool closeKeyboard = false)
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->send_text_to_active_keyboard(
+ CAddonBase::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 ATTRIBUTE_HIDDEN IsKeyboardActivated()
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->is_keyboard_activated(CAddonBase::m_interface->toKodi->kodiBase);
- }
- //--------------------------------------------------------------------------
- };
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Keyboard
+/// @brief Check for visible keyboard on GUI.
+///
+/// @return true if keyboard present, false if not present
+///
+inline bool ATTRIBUTE_HIDDEN IsKeyboardActivated()
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->dialogKeyboard->is_keyboard_activated(
+ CAddonBase::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
index bff76830fa..835a8d4ccd 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Numeric.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Numeric.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/numeric.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,345 +20,327 @@ namespace gui
namespace dialogs
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_Numeric Dialog Numeric
- /// \ingroup cpp_kodi_gui
- /// @{
- /// @brief \cpp_namespace{ kodi::gui::dialogs::Numeric }
- /// **Numeric dialogs**
- ///
- /// 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
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndVerifyNewPassword(std::string& newPassword)
+{
+ using namespace ::kodi::addon;
+ char* pw = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_new_password(
+ CAddonBase::m_interface->toKodi->kodiBase, &pw);
+ if (pw != nullptr)
{
- //==========================================================================
- ///
- /// \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 ATTRIBUTE_HIDDEN ShowAndVerifyNewPassword(std::string& newPassword)
- {
- using namespace ::kodi::addon;
- char* pw = nullptr;
- bool ret =
- CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_new_password(
- CAddonBase::m_interface->toKodi->kodiBase, &pw);
- if (pw != nullptr)
- {
- newPassword = pw;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, pw);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+ newPassword = pw;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 successfull 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 ATTRIBUTE_HIDDEN ShowAndVerifyPassword(const std::string& password,
- const std::string& heading,
- int retries)
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_password(CAddonBase::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] 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 successfull 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 ATTRIBUTE_HIDDEN ShowAndVerifyPassword(const std::string& password,
+ const std::string& heading,
+ int retries)
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_password(
+ CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndVerifyInput(std::string& toVerify,
- const std::string& heading,
- bool verifyInput)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_input(CAddonBase::m_interface->toKodi->kodiBase,
- toVerify.c_str(), &retString, heading.c_str(), verifyInput);
- if (retString != nullptr)
- {
- toVerify = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndVerifyInput(std::string& toVerify,
+ const std::string& heading,
+ bool verifyInput)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_verify_input(
+ CAddonBase::m_interface->toKodi->kodiBase, toVerify.c_str(), &retString, heading.c_str(),
+ verifyInput);
+ if (retString != nullptr)
+ {
+ toVerify = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetTime(tm& time, const std::string& heading)
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_time(CAddonBase::m_interface->toKodi->kodiBase, &time, heading.c_str());
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndGetTime(tm& time, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_time(
+ CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetDate(tm& date, const std::string& heading)
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_date(CAddonBase::m_interface->toKodi->kodiBase, &date, 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 ATTRIBUTE_HIDDEN ShowAndGetDate(tm& date, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_date(
+ CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetIPAddress(std::string& ipAddress,
- const std::string& heading)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_ip_address(CAddonBase::m_interface->toKodi->kodiBase,
- ipAddress.c_str(), &retString, heading.c_str());
- if (retString != nullptr)
- {
- ipAddress = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, retString);
- }
- return ret;
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndGetIPAddress(std::string& ipAddress, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_ip_address(
+ CAddonBase::m_interface->toKodi->kodiBase, ipAddress.c_str(), &retString, heading.c_str());
+ if (retString != nullptr)
+ {
+ ipAddress = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 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 ATTRIBUTE_HIDDEN ShowAndGetNumber(std::string& input,
- const std::string& heading,
- unsigned int autoCloseTimeoutMs = 0)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_number(CAddonBase::m_interface->toKodi->kodiBase,
- input.c_str(), &retString, heading.c_str(), autoCloseTimeoutMs);
- if (retString != nullptr)
- {
- input = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetNumber(std::string& input,
+ const std::string& heading,
+ unsigned int autoCloseTimeoutMs = 0)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_number(
+ CAddonBase::m_interface->toKodi->kodiBase, input.c_str(), &retString, heading.c_str(),
+ autoCloseTimeoutMs);
+ if (retString != nullptr)
+ {
+ input = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetSeconds(std::string& time, const std::string& heading)
- {
- using namespace ::kodi::addon;
- char* retString = nullptr;
- bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_seconds(CAddonBase::m_interface->toKodi->kodiBase,
- time.c_str(), &retString, heading.c_str());
- if (retString != nullptr)
- {
- time = retString;
- CAddonBase::m_interface->toKodi->free_string(CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetSeconds(std::string& time, const std::string& heading)
+{
+ using namespace ::kodi::addon;
+ char* retString = nullptr;
+ bool ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogNumeric->show_and_get_seconds(
+ CAddonBase::m_interface->toKodi->kodiBase, time.c_str(), &retString, heading.c_str());
+ if (retString != nullptr)
+ {
+ time = retString;
+ CAddonBase::m_interface->toKodi->free_string(CAddonBase::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
index b9a3a0d659..747ab9d3fb 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/OK.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/OK.h
@@ -9,7 +9,9 @@
#pragma once
#include "../../AddonBase.h"
-#include "../definitions.h"
+#include "../../c-api/gui/dialogs/ok.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,82 +20,82 @@ namespace gui
namespace dialogs
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_OK Dialog OK
- /// \ingroup cpp_kodi_gui
- /// @{
- /// @brief \cpp_namespace{ kodi::gui::dialogs::OK }
- /// **OK dialog**
- ///
- /// 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 ATTRIBUTE_HIDDEN ShowAndGetInput(const std::string& heading, const std::string& text)
- {
- using namespace ::kodi::addon;
- CAddonBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_single_text(
- CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), text.c_str());
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndGetInput(const std::string& heading, const std::string& text)
+{
+ using namespace ::kodi::addon;
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_single_text(
+ CAddonBase::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 ATTRIBUTE_HIDDEN ShowAndGetInput(const std::string& heading,
- const std::string& line0,
- const std::string& line1,
- const std::string& line2)
- {
- using namespace ::kodi::addon;
- CAddonBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_line_text(CAddonBase::m_interface->toKodi->kodiBase,
- heading.c_str(), line0.c_str(), line1.c_str(),
- line2.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 ATTRIBUTE_HIDDEN ShowAndGetInput(const std::string& heading,
+ const std::string& line0,
+ const std::string& line1,
+ const std::string& line2)
+{
+ using namespace ::kodi::addon;
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_line_text(
+ CAddonBase::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
index b1f8cc5520..d242a565ee 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Progress.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Progress.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/progress.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,14 +20,12 @@ namespace gui
namespace dialogs
{
-//============================================================================
-///
-/// \defgroup cpp_kodi_gui_dialogs_CProgress Dialog Progress
-/// \ingroup cpp_kodi_gui
-/// @brief \cpp_class{ kodi::gui::dialogs::CProgress }
-/// **Progress dialog shown in center**
-///
-/// The with \ref DialogProgress.h "#include <kodi/gui/dialogs/Progress.h>"
+//==============================================================================
+/// @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.
///
@@ -52,9 +52,8 @@ namespace dialogs
class ATTRIBUTE_HIDDEN CProgress
{
public:
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief Construct a new dialog
///
CProgress()
@@ -66,11 +65,10 @@ public:
kodi::Log(ADDON_LOG_FATAL,
"kodi::gui::dialogs::CProgress can't create window class from Kodi !!!");
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief Destructor
///
~CProgress()
@@ -80,11 +78,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->delete_dialog(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief To open the dialog
///
void Open()
@@ -93,11 +90,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->open(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief Set the heading title of dialog
///
/// @param[in] heading Title string to use
@@ -108,11 +104,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->set_heading(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, heading.c_str());
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief To set the line text field on dialog from 0 - 2
///
/// @param[in] iLine Line number
@@ -124,11 +119,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->set_line(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, iLine, line.c_str());
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief To enable and show cancel button on dialog
///
/// @param[in] canCancel if true becomes it shown
@@ -139,11 +133,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->set_can_cancel(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, canCancel);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief To check dialog for clicked cancel button
///
/// @return True if canceled
@@ -154,11 +147,10 @@ public:
return CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->is_canceled(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief Get the current progress position as percent
///
/// @param[in] percentage Position to use from 0 to 100
@@ -169,11 +161,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->set_percentage(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, percentage);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief To set the current progress position as percent
///
/// @return Current Position used from 0 to 100
@@ -184,11 +175,10 @@ public:
return CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->get_percentage(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief To show or hide progress bar dialog
///
/// @param[in] onOff If true becomes it shown
@@ -199,11 +189,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->show_progress_bar(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, onOff);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @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
@@ -214,11 +203,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->set_progress_max(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, max);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @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
@@ -229,11 +217,10 @@ public:
CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->set_progress_advance(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle, steps);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_CProgress
+ //============================================================================
+ /// @ingroup cpp_kodi_gui_dialogs_CProgress
/// @brief To check progress was canceled on work
///
/// @return True if aborted
@@ -244,12 +231,14 @@ public:
return CAddonBase::m_interface->toKodi->kodi_gui->dialogProgress->abort(
CAddonBase::m_interface->toKodi->kodiBase, m_DialogHandle);
}
- //--------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
private:
- void* m_DialogHandle;
+ 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
index 39a98fe133..9b1923e94f 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Select.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/Select.h
@@ -8,28 +8,37 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/select.h"
+
+#ifdef __cplusplus
+
+namespace kodi
+{
+namespace gui
+{
+namespace dialogs
+{
//==============================================================================
-/// \defgroup cpp_kodi_vfs_Defs Definitions, structures and enumerators
-/// \ingroup cpp_kodi_gui_dialogs_Select
-/// @brief **Dialog Select definition values**
+/// @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_vfs_Defs
-/// @brief **Selection entry structure**
+/// @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
{
- //============================================================================
- /// Structure constructor
- ///
- /// There becomes selected always set to false.
- ///
+ /*! \cond PRIVATE */
SSelectionEntry() = default;
- //----------------------------------------------------------------------------
+ /*! \endcond */
/// Entry identfication string
std::string id;
@@ -43,227 +52,218 @@ typedef struct SSelectionEntry
} SSelectionEntry;
//------------------------------------------------------------------------------
-namespace kodi
-{
-namespace gui
+//==============================================================================
+/// @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
{
-namespace dialogs
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN Show(const std::string& heading,
+ const std::vector<std::string>& entries,
+ int selected = -1,
+ unsigned int autoclose = 0)
{
-
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_Select Dialog Select
- /// \ingroup cpp_kodi_gui
- /// @{
- /// @brief \cpp_namespace{ kodi::gui::dialogs::Select }
- /// **Selection dialog**
- ///
- /// 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
+ 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)
{
- //==========================================================================
- ///
- /// \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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open(
- CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size, selected,
- autoclose);
- free(cEntries);
- return ret;
- }
- //--------------------------------------------------------------------------
+ cEntries[i] = entries[i].c_str();
+ }
+ int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open(
+ CAddonBase::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 SSelectionEntry, where a ID string can be defined.
- ///
- /// @param[in] heading Dialog heading name
- /// @param[in] entries SSelectionEntry list about entries
- /// @param[in] selected [opt] Predefined selection (default is
- /// <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<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 ATTRIBUTE_HIDDEN Show(const std::string& heading,
- std::vector<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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(),
- cEntries, size, selected, autoclose);
- if (ret >= 0)
- {
- entries[ret].selected = true;
- }
- free(cEntries);
- return ret;
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @ingroup cpp_kodi_gui_dialogs_Select
+/// @brief Show a 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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open(
+ CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size, selected,
+ autoclose);
+ if (ret >= 0)
+ {
+ entries[ret].selected = true;
+ }
+ free(cEntries);
+ return ret;
+}
+//------------------------------------------------------------------------------
- //==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_dialogs_Select
- /// @brief Show a multiple selection dialog about given parts.
- ///
- /// @param[in] heading Dialog heading name
- /// @param[in] entries SSelectionEntry list about entries
- /// @param[in] autoclose [opt] To close dialog automatic after the given
- /// time in ms. As '0' it stays open.
- /// @return The selected entries, if return <tt>empty</tt> was
- /// nothing selected or canceled
- ///
- /// With selected on SSelectionEntry can be a pre selection defined.
- ///
- ///-------------------------------------------------------------------------
- ///
- /// **Example:**
- /// ~~~~~~~~~~~~~{.cpp}
- /// #include <kodi/gui/dialogs/Select.h>
- ///
- /// std::vector<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 ATTRIBUTE_HIDDEN ShowMultiSelect(const std::string& heading,
- std::vector<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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open_multi_select(CAddonBase::m_interface->toKodi->kodiBase,
- heading.c_str(), cEntryIDs, cEntryNames,
- cEntriesSelected, size, autoclose);
- if (ret)
- {
- for (unsigned int i = 0; i < size; ++i)
- entries[i].selected = cEntriesSelected[i];
- }
- free(cEntryNames);
- free(cEntryIDs);
- free(cEntriesSelected);
- return ret;
- }
- //--------------------------------------------------------------------------
- };
- /// @}
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN 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 = CAddonBase::m_interface->toKodi->kodi_gui->dialogSelect->open_multi_select(
+ CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntryIDs, cEntryNames,
+ cEntriesSelected, size, autoclose);
+ if (ret)
+ {
+ for (unsigned int i = 0; i < size; ++i)
+ entries[i].selected = cEntriesSelected[i];
+ }
+ free(cEntryNames);
+ free(cEntryIDs);
+ free(cEntriesSelected);
+ return ret;
+}
+//------------------------------------------------------------------------------
+}; // 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
index 5c81837d49..42a86f39a4 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/TextViewer.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/TextViewer.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/text_viewer.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,91 +20,90 @@ namespace gui
namespace dialogs
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_TextViewer Dialog Text Viewer
- /// \ingroup cpp_kodi_gui
- /// @{
- /// @brief \cpp_namespace{ kodi::gui::dialogs::TextViewer }
- /// **Text viewer dialog**
- ///
- /// 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 Small 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 ATTRIBUTE_HIDDEN Show(const std::string& heading, const std::string& text)
- {
- using namespace ::kodi::addon;
- CAddonBase::m_interface->toKodi->kodi_gui->dialogTextViewer->open(
- CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), text.c_str());
- }
- //--------------------------------------------------------------------------
- };
- /// @}
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN Show(const std::string& heading, const std::string& text)
+{
+ using namespace ::kodi::addon;
+ CAddonBase::m_interface->toKodi->kodi_gui->dialogTextViewer->open(
+ CAddonBase::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
index 67c2fc46d0..6e6e069ea0 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/YesNo.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/dialogs/YesNo.h
@@ -8,8 +8,10 @@
#pragma once
-#include "../definitions.h"
#include "../../AddonBase.h"
+#include "../../c-api/gui/dialogs/yes_no.h"
+
+#ifdef __cplusplus
namespace kodi
{
@@ -18,171 +20,169 @@ namespace gui
namespace dialogs
{
- //============================================================================
- ///
- /// \defgroup cpp_kodi_gui_dialogs_YesNo Dialog Yes/No
- /// \ingroup cpp_kodi_gui
- /// @{
- /// @brief \cpp_namespace{ kodi::gui::dialogs::YesNo }
- /// **Yes / No dialog**
- ///
- /// 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;
- /// 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 ATTRIBUTE_HIDDEN ShowAndGetInput(const std::string& heading,
- const std::string& text,
- bool& canceled,
- const std::string& noLabel = "",
- const std::string& yesLabel = "")
- {
- using namespace ::kodi::addon;
- return CAddonBase::m_interface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_single_text(
- CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), text.c_str(), &canceled,
- noLabel.c_str(), yesLabel.c_str());
- }
- //--------------------------------------------------------------------------
+//==============================================================================
+/// @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 ATTRIBUTE_HIDDEN ShowAndGetInput(const std::string& heading,
+ const std::string& text,
+ bool& canceled,
+ const std::string& noLabel = "",
+ const std::string& yesLabel = "")
+{
+ using namespace ::kodi::addon;
+ return CAddonBase::m_interface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_single_text(
+ CAddonBase::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 ATTRIBUTE_HIDDEN 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 CAddonBase::m_interface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_text(CAddonBase::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.
+///
+/// @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 ATTRIBUTE_HIDDEN 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 CAddonBase::m_interface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_text(
+ CAddonBase::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;
- /// 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 ATTRIBUTE_HIDDEN 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 CAddonBase::m_interface->toKodi->kodi_gui->dialogYesNo->show_and_get_input_line_button_text(CAddonBase::m_interface->toKodi->kodiBase,
- heading.c_str(), line0.c_str(), line1.c_str(), line2.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
+/// 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 ATTRIBUTE_HIDDEN 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 CAddonBase::m_interface->toKodi->kodi_gui->dialogYesNo
+ ->show_and_get_input_line_button_text(
+ CAddonBase::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/GL.h b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h
index 943c7d0b0b..16d43e37b4 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GL.h
@@ -8,28 +8,25 @@
#pragma once
+#ifdef __cplusplus
+
//==============================================================================
-///
-/// \defgroup cpp_kodi_gui_gl OpenGL helpers
-/// \ingroup cpp_kodi_gui
-/// \brief Auxiliary functions for Open GL
-///
+/// @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>".
-///
+/// 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
+/// 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
+/// 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>.
///
@@ -41,7 +38,7 @@
///
///----------------------------------------------------------------------------
///
-/// In addition, \ref BUFFER_OFFSET is declared in it which can be used to give an
+/// In addition, @ref BUFFER_OFFSET is declared in it which can be used to give an
/// offset on the array to GL.
///
/// **Example:**
@@ -63,49 +60,53 @@
/// ~~~~~~~~~~~~~~~~~
#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
+#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
+#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
-#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
+/// @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
index 7a6a0a1ddc..4dd97af22f 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GLonDX.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/GLonDX.h
@@ -8,16 +8,18 @@
#pragma once
+#ifdef __cplusplus
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
#include <angle_gl.h>
#include <d3d11.h>
#include <d3dcompiler.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
#include <kodi/AddonBase.h>
#include <kodi/gui/General.h>
#include <wrl/client.h>
-#pragma comment( lib, "d3dcompiler.lib" )
+#pragma comment(lib, "d3dcompiler.lib")
#ifndef GL_CLIENT_VERSION
#define GL_CLIENT_VERSION 3
#endif
@@ -32,33 +34,41 @@ namespace gl
class ATTRIBUTE_HIDDEN CGLonDX : public kodi::gui::IRenderHelper
{
public:
- explicit CGLonDX() : m_pContext(reinterpret_cast<ID3D11DeviceContext*>(kodi::gui::GetHWContext())) {}
+ 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);
+ 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());
@@ -72,7 +82,8 @@ public:
}
EGLint numConfigs = 0;
- if (eglChooseConfig(m_eglDisplay, egl_config_attrs, &m_eglConfig, 1, &numConfigs) != EGL_TRUE || 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;
@@ -165,7 +176,7 @@ private:
Microsoft::WRL::ComPtr<ID3D11Resource> pRTResource;
Microsoft::WRL::ComPtr<ID3D11Texture2D> pRTTexture;
Microsoft::WRL::ComPtr<ID3D11Texture2D> pOffScreenTexture;
- Microsoft::WRL::ComPtr<IDXGIResource> dxgiResource;
+ Microsoft::WRL::ComPtr<IDXGIResource> dxgiResource;
m_pContext->GetDevice(&pDevice);
m_pContext->OMGetRenderTargets(1, &pRTView, nullptr);
@@ -187,7 +198,8 @@ private:
return false;
}
- CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc(pOffScreenTexture.Get(), D3D11_SRV_DIMENSION_TEXTURE2D);
+ 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");
@@ -215,18 +227,19 @@ private:
}
// 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);
+ 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)
{
@@ -236,13 +249,15 @@ private:
return true;
}
- HRESULT d3dCreateShader(ShaderType shaderType, const std::string& source, IUnknown** ppShader) const
+ 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);
+ shaderType == PIXEL_SHADER ? "ps_4_0" : "vs_4_0", 0, 0, &pBlob, &pErrors);
if (SUCCEEDED(hr))
{
@@ -252,18 +267,18 @@ private:
if (shaderType == PIXEL_SHADER)
{
hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr,
- reinterpret_cast<ID3D11PixelShader**>(ppShader));
+ reinterpret_cast<ID3D11PixelShader**>(ppShader));
}
else
{
hr = pDevice->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr,
- reinterpret_cast<ID3D11VertexShader**>(ppShader));
+ reinterpret_cast<ID3D11VertexShader**>(ppShader));
}
if (FAILED(hr))
{
Log(ADDON_LOG_ERROR, "GLonDX: unable to create %s shader",
- shaderType == PIXEL_SHADER ? "pixel" : "vertex");
+ shaderType == PIXEL_SHADER ? "pixel" : "vertex");
}
}
else
@@ -275,7 +290,9 @@ private:
static const char* eglGetErrorString()
{
-#define CASE_STR( value ) case value: return #value
+#define CASE_STR(value) \
+ case value: \
+ return #value
switch (eglGetError())
{
CASE_STR(EGL_SUCCESS);
@@ -293,8 +310,8 @@ private:
CASE_STR(EGL_BAD_NATIVE_PIXMAP);
CASE_STR(EGL_BAD_NATIVE_WINDOW);
CASE_STR(EGL_CONTEXT_LOST);
- default:
- return "Unknown";
+ default:
+ return "Unknown";
}
#undef CASE_STR
}
@@ -338,9 +355,10 @@ private:
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)
- {
+ 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);
});
@@ -367,3 +385,5 @@ private:
using CRenderHelper = gl::CGLonDX;
} /* namespace gui */
} /* namespace kodi */
+
+#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
index 209f2746f5..bf6d48c03d 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/Shader.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/gl/Shader.h
@@ -10,9 +10,11 @@
#include "GL.h"
+#ifdef __cplusplus
+
#include <stdio.h>
-#include <vector>
#include <string>
+#include <vector>
#include <kodi/AddonBase.h>
#include <kodi/Filesystem.h>
@@ -34,8 +36,7 @@ class ATTRIBUTE_HIDDEN CShader
public:
CShader() = default;
virtual ~CShader() = default;
- virtual bool Compile(const std::string& extraBegin = "",
- const std::string& extraEnd = "") = 0;
+ virtual bool Compile(const std::string& extraBegin = "", const std::string& extraEnd = "") = 0;
virtual void Free() = 0;
virtual GLuint Handle() = 0;
@@ -46,7 +47,8 @@ public:
kodi::vfs::CFile source;
if (!source.OpenFile(file))
{
- kodi::Log(ADDON_LOG_ERROR, "CShader::%s: Failed to open file '%s'", __FUNCTION__, file.c_str());
+ 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));
@@ -80,8 +82,7 @@ public:
m_vertexShader = 0;
}
- bool Compile(const std::string& extraBegin = "",
- const std::string& extraEnd = "") override
+ bool Compile(const std::string& extraBegin = "", const std::string& extraEnd = "") override
{
GLint params[4];
@@ -90,7 +91,7 @@ public:
m_vertexShader = glCreateShader(GL_VERTEX_SHADER);
GLsizei count = 0;
- const char *sources[3];
+ const char* sources[3];
if (!extraBegin.empty())
sources[count++] = extraBegin.c_str();
if (!m_source.empty())
@@ -141,8 +142,7 @@ public:
m_pixelShader = 0;
}
- bool Compile(const std::string& extraBegin = "",
- const std::string& extraEnd = "") override
+ bool Compile(const std::string& extraBegin = "", const std::string& extraEnd = "") override
{
GLint params[4];
@@ -151,7 +151,7 @@ public:
m_pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
GLsizei count = 0;
- const char *sources[3];
+ const char* sources[3];
if (!extraBegin.empty())
sources[count++] = extraBegin.c_str();
if (!m_source.empty())
@@ -189,16 +189,14 @@ protected:
//------------------------------------------------------------------------
//============================================================================
-///
-/// \defgroup cpp_kodi_gui_gl_CShaderProgram GL Shader Program
-/// \ingroup cpp_kodi_gui_gl
-/// @brief \cpp_class{ kodi::gui::gl::CShaderProgram }
-/// **Class to manage an OpenGL shader program**
-///
+/// @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>"
+/// It has the header @ref Shader.h "#include <kodi/gui/gl/Shader.h>"
/// be included to enjoy it.
///
/// ----------------------------------------------------------------------------
@@ -275,58 +273,45 @@ protected:
/// ADDONCREATOR(CExample);
/// ~~~~~~~~~~~~~
///
-
-//========================================================================
-/// CShaderProgram
class ATTRIBUTE_HIDDEN CShaderProgram
{
public:
//==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief Construct a new shader.
///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief Construct a new shader
- ///
- /// Load must be done later with \ref LoadShaderFiles.
+ /// Load must be done later with @ref LoadShaderFiles.
///
CShaderProgram() = default;
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief Construct a new shader and load defined shader files
+ /// @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);
- }
+ CShaderProgram(const std::string& vert, const std::string& frag) { LoadShaderFiles(vert, frag); }
//--------------------------------------------------------------------------
//==========================================================================
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief Destructor.
///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief Destructor
- ///
- virtual ~CShaderProgram()
- {
- ShaderFree();
- }
+ virtual ~CShaderProgram() { ShaderFree(); }
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief To load manually the needed shader files
+ /// @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.
+ /// here or via @ref CompileAndLink, or both of the source code.
///
bool LoadShaderFiles(const std::string& vert, const std::string& frag)
{
@@ -347,9 +332,8 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief To compile and link the shader to the GL interface
+ /// @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
@@ -421,7 +405,7 @@ public:
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);
+ fprintf(stderr, "CShaderProgram::%s: %s@n", __FUNCTION__, log);
ShaderFree();
return false;
}
@@ -434,14 +418,13 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief To activate the shader and use it on the GPU
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To activate the shader and use it on the GPU.
///
/// @return true if enable was successfull done
///
///
- /// @note During this call, the \ref OnEnabled stored in the child is also
+ /// @note During this call, the @ref OnEnabled stored in the child is also
/// called
///
bool EnableShader()
@@ -480,9 +463,8 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief To deactivate the shader use on the GPU
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
+ /// @brief To deactivate the shader use on the GPU.
///
void DisableShader()
{
@@ -495,8 +477,7 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram
/// @brief Used to check if shader has been loaded before.
///
/// @return true if enable was successfull done
@@ -507,9 +488,8 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief To get the vertex shader class used by Kodi at the addon
+ /// @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
///
@@ -517,9 +497,8 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief To get the fragment shader class used by Kodi at the addon
+ /// @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
///
@@ -527,9 +506,8 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief Used to get the definition created in the OpenGL itself
+ /// @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
///
@@ -537,24 +515,22 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \defgroup cpp_kodi_gui_gl_CShaderProgram_child Child Functions
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram
- /// @brief \cpp_class{ kodi::gui::gl::CShaderProgram child functions }
+ /// @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_gl_CShaderProgram_child
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram_child
/// @brief Mandatory child function to set the necessary CPU to GPU data
///
- virtual void OnCompiledAndLinked() {};
+ virtual void OnCompiledAndLinked(){};
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram_child
+ /// @ingroup cpp_kodi_gui_helpers_gl_CShaderProgram_child
/// @brief Optional function to exchange data between CPU and GPU while
/// activating the shader
///
@@ -564,13 +540,12 @@ public:
//--------------------------------------------------------------------------
//==========================================================================
- ///
- /// \ingroup cpp_kodi_gui_gl_CShaderProgram_child
+ /// @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() {};
+ virtual void OnDisabled(){};
//--------------------------------------------------------------------------
- //@}
+ /// @}
private:
void ShaderFree()
@@ -592,3 +567,5 @@ private:
} /* 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 0000000000..4c816a4309
--- /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 0000000000..d5769749ff
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/input/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(HEADERS ActionIDs.h)
+
+if(NOT ENABLE_STATIC_LIBS)
+ core_add_library(addons_kodi-dev-kit_include_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
index 2e96d21ceb..dabe101cb0 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/gui/renderHelper.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/gui/renderHelper.h
@@ -10,6 +10,8 @@
#include "../AddonBase.h"
+#ifdef __cplusplus
+
namespace kodi
{
namespace gui
@@ -37,8 +39,8 @@ namespace gui
struct ATTRIBUTE_HIDDEN CRenderHelperStub : public IRenderHelper
{
bool Init() override { return true; }
- void Begin() override { }
- void End() override { }
+ void Begin() override {}
+ void End() override {}
}; /* class CRenderHelperStub */
using CRenderHelper = CRenderHelperStub;
@@ -76,3 +78,5 @@ inline std::shared_ptr<IRenderHelper> ATTRIBUTE_HIDDEN GetRenderHelper()
} /* namespace gui */
} /* namespace kodi */
+
+#endif /* __cplusplus */
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
index ef2d728892..245abd6660 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/System.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/platform/android/System.h
@@ -9,44 +9,37 @@
#pragma once
#include "../../AddonBase.h"
+#include "../../c-api/platform/android/system.h"
-/*
- * 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
- */
-
-static const char* INTERFACE_ANDROID_SYSTEM_NAME = "ANDROID_SYSTEM";
-static const char* INTERFACE_ANDROID_SYSTEM_VERSION = "1.0.1";
-static const char* INTERFACE_ANDROID_SYSTEM_VERSION_MIN = "1.0.1";
-
-struct AddonToKodiFuncTable_android_system
+#ifdef __cplusplus
+namespace kodi
+{
+namespace platform
{
- void* (*get_jni_env)();
- int (*get_sdk_version)();
- const char *(*get_class_name)();
-};
//==============================================================================
+/// @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.
///
-/// \defgroup cpp_kodi_platform Interface - kodi::platform
-/// \ingroup cpp
-/// @brief **Android platform specific functions**
+/// It has the header is @ref System.h "#include <kodi/platform/android/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
+/// ~~~~~~~~~~~~~
///
-//------------------------------------------------------------------------------
-
-namespace kodi
-{
-namespace platform
-{
class ATTRIBUTE_HIDDEN CInterfaceAndroidSystem
{
public:
@@ -55,13 +48,12 @@ public:
GetInterface(INTERFACE_ANDROID_SYSTEM_NAME, INTERFACE_ANDROID_SYSTEM_VERSION))){};
//============================================================================
+ /// @ingroup cpp_kodi_platform_CInterfaceAndroidSystem
+ /// @brief Request an JNI env pointer for the calling thread.
///
- /// \ingroup cpp_kodi_platform
- /// @brief request an JNI env pointer for the calling thread.
/// JNI env has to be controlled by kodi because of the underlying
/// threading concep.
///
- /// @param[in]:
/// @return JNI env pointer for the calling thread
///
inline void* GetJNIEnv()
@@ -74,11 +66,9 @@ public:
//----------------------------------------------------------------------------
//============================================================================
+ /// @ingroup cpp_kodi_platform_CInterfaceAndroidSystem
+ /// @brief Request the android sdk version to e.g. initialize <b>`JNIBase`</b>.
///
- /// \ingroup cpp_kodi_platform
- /// @brief request the android sdk version to e.g. initialize JNIBase.
- ///
- /// @param[in]:
/// @return Android SDK version
///
inline int GetSDKVersion()
@@ -88,13 +78,12 @@ public:
return 0;
}
+ //----------------------------------------------------------------------------
//============================================================================
+ /// @ingroup cpp_kodi_platform_CInterfaceAndroidSystem
+ /// @brief Request the android main class name e.g. <b>`org.xbmc.kodi`</b>.
///
- /// \ingroup cpp_kodi_platform
- /// @brief request the android main class name e.g. org.xbmc.kodi.
- ///
- /// @param[in]:
/// @return package class name
///
inline std::string GetClassName()
@@ -104,11 +93,13 @@ public:
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/versions.h b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
index 6e4ab3ff55..a81fa7e6eb 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
@@ -46,10 +46,11 @@
#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.14.1"
-#define ADDON_GLOBAL_VERSION_GUI_MIN "5.14.0"
+#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 "ActionIDs.h" \
+#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"
@@ -58,7 +59,7 @@
#define ADDON_GLOBAL_VERSION_AUDIOENGINE_DEPENDS "AudioEngine.h" \
"c-api/audio_engine.h"
-#define ADDON_GLOBAL_VERSION_FILESYSTEM "1.1.4"
+#define ADDON_GLOBAL_VERSION_FILESYSTEM "1.1.6"
#define ADDON_GLOBAL_VERSION_FILESYSTEM_MIN "1.1.0"
#define ADDON_GLOBAL_VERSION_FILESYSTEM_XML_ID "kodi.binary.global.filesystem"
#define ADDON_GLOBAL_VERSION_FILESYSTEM_DEPENDS "Filesystem.h" \
@@ -89,8 +90,8 @@
#define ADDON_INSTANCE_VERSION_AUDIOENCODER_DEPENDS "c-api/addon-instance/audio_encoder.h" \
"addon-instance/AudioEncoder.h"
-#define ADDON_INSTANCE_VERSION_GAME "2.0.2"
-#define ADDON_INSTANCE_VERSION_GAME_MIN "2.0.1"
+#define ADDON_INSTANCE_VERSION_GAME "2.1.0"
+#define ADDON_INSTANCE_VERSION_GAME_MIN "2.1.0"
#define ADDON_INSTANCE_VERSION_GAME_XML_ID "kodi.binary.instance.game"
#define ADDON_INSTANCE_VERSION_GAME_DEPENDS "addon-instance/Game.h"
@@ -104,8 +105,8 @@
#define ADDON_INSTANCE_VERSION_INPUTSTREAM_XML_ID "kodi.binary.instance.inputstream"
#define ADDON_INSTANCE_VERSION_INPUTSTREAM_DEPENDS "addon-instance/Inputstream.h"
-#define ADDON_INSTANCE_VERSION_PERIPHERAL "1.3.9"
-#define ADDON_INSTANCE_VERSION_PERIPHERAL_MIN "1.3.8"
+#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"
@@ -141,10 +142,11 @@
#define ADDON_INSTANCE_VERSION_SCREENSAVER_DEPENDS "c-api/addon-instance/screensaver.h" \
"addon-instance/Screensaver.h"
-#define ADDON_INSTANCE_VERSION_VFS "2.3.2"
-#define ADDON_INSTANCE_VERSION_VFS_MIN "2.3.1"
+#define ADDON_INSTANCE_VERSION_VFS "3.0.0"
+#define ADDON_INSTANCE_VERSION_VFS_MIN "3.0.0"
#define ADDON_INSTANCE_VERSION_VFS_XML_ID "kodi.binary.instance.vfs"
-#define ADDON_INSTANCE_VERSION_VFS_DEPENDS "addon-instance/VFS.h"
+#define ADDON_INSTANCE_VERSION_VFS_DEPENDS "c-api/addon-instance/vfs.h" \
+ "addon-instance/VFS.h"
#define ADDON_INSTANCE_VERSION_VISUALIZATION "3.0.0"
#define ADDON_INSTANCE_VERSION_VISUALIZATION_MIN "3.0.0"
diff --git a/xbmc/addons/test/TestAddonBuilder.cpp b/xbmc/addons/test/TestAddonBuilder.cpp
index 69559e2f7f..1f2366b6df 100644
--- a/xbmc/addons/test/TestAddonBuilder.cpp
+++ b/xbmc/addons/test/TestAddonBuilder.cpp
@@ -34,7 +34,8 @@ TEST_F(TestAddonBuilder, ShouldBuildDependencyAddons)
CAddonInfoBuilder::CFromDB builder;
builder.SetId("aa");
builder.SetDependencies(deps);
- builder.SetType(ADDON_UNKNOWN);
+ CAddonType addonType(ADDON_UNKNOWN);
+ builder.SetExtensions(addonType);
AddonPtr addon = CAddonBuilder::Generate(builder.get(), ADDON_UNKNOWN);
EXPECT_EQ(deps, addon->GetDependencies());
}
@@ -43,7 +44,8 @@ TEST_F(TestAddonBuilder, ShouldReturnDerivedType)
{
CAddonInfoBuilder::CFromDB builder;
builder.SetId("aa");
- builder.SetType(ADDON_RESOURCE_LANGUAGE);
+ CAddonType addonType(ADDON_RESOURCE_LANGUAGE);
+ builder.SetExtensions(addonType);
auto addon = std::dynamic_pointer_cast<CLanguageResource>(CAddonBuilder::Generate(builder.get(), ADDON_UNKNOWN));
EXPECT_NE(nullptr, addon);
}
diff --git a/xbmc/addons/test/TestAddonDatabase.cpp b/xbmc/addons/test/TestAddonDatabase.cpp
index 87a019ca72..693549af22 100644
--- a/xbmc/addons/test/TestAddonDatabase.cpp
+++ b/xbmc/addons/test/TestAddonDatabase.cpp
@@ -35,7 +35,7 @@ protected:
std::set<std::string> installed{"repository.a", "repository.b"};
database.SyncInstalled(installed, installed, std::set<std::string>());
- VECADDONS addons;
+ std::vector<AddonInfoPtr> addons;
CreateAddon(addons, "foo.bar", "1.0.0");
database.SetRepoUpdateData("repository.a", {});
database.UpdateRepositoryContent("repository.a", AddonVersion("1.0.0"), "test", addons);
@@ -46,13 +46,12 @@ protected:
database.UpdateRepositoryContent("repository.b", AddonVersion("1.0.0"), "test", addons);
}
- void CreateAddon(VECADDONS& addons, std::string id, std::string version)
+ void CreateAddon(std::vector<AddonInfoPtr>& addons, std::string id, std::string version)
{
CAddonInfoBuilder::CFromDB builder;
builder.SetId(id);
builder.SetVersion(AddonVersion(version));
- AddonPtr addon = CAddonBuilder::Generate(builder.get(), ADDON_UNKNOWN);
- addons.push_back(addon);
+ addons.push_back(builder.get());
}
void TearDown() override
diff --git a/xbmc/addons/test/TestAddonInfoBuilder.cpp b/xbmc/addons/test/TestAddonInfoBuilder.cpp
index e7df9678bb..eac9905b68 100644
--- a/xbmc/addons/test/TestAddonInfoBuilder.cpp
+++ b/xbmc/addons/test/TestAddonInfoBuilder.cpp
@@ -129,7 +129,9 @@ TEST_F(TestAddonInfoBuilder, TestGenerate_DBEntry)
CAddonInfoBuilder::CFromDB builder;
builder.SetId("video.blablabla.org");
builder.SetVersion(AddonVersion("1.2.3"));
- builder.SetType(ADDON_PLUGIN);
+ CAddonType addonType(ADDON_PLUGIN);
+ addonType.Insert("provides", "video audio");
+ builder.SetExtensions(addonType);
builder.SetName("The Bla Bla Bla Addon");
builder.SetAuthor("Team Kodi");
builder.SetSummary("Summary bla bla bla");
@@ -141,7 +143,6 @@ TEST_F(TestAddonInfoBuilder, TestGenerate_DBEntry)
builder.SetEMail("a@a.dummy");
builder.SetSource("https://github.com/xbmc/xbmc");
InfoMap extrainfo;
- extrainfo["provides"] = "video audio";
extrainfo["language"] = "marsian";
builder.SetExtrainfo(extrainfo);
diff --git a/xbmc/commons/ilog.h b/xbmc/commons/ilog.h
index a4e14efafe..f8ac6856fe 100644
--- a/xbmc/commons/ilog.h
+++ b/xbmc/commons/ilog.h
@@ -17,12 +17,10 @@
// ones we use in the code
#define LOGDEBUG 0
#define LOGINFO 1
-#define LOGNOTICE 2
-#define LOGWARNING 3
-#define LOGERROR 4
-#define LOGSEVERE 5
-#define LOGFATAL 6
-#define LOGNONE 7
+#define LOGWARNING 2
+#define LOGERROR 3
+#define LOGFATAL 4
+#define LOGNONE 5
// extra masks - from bit 5
#define LOGMASKBIT 5
diff --git a/xbmc/cores/AudioEngine/AEResampleFactory.cpp b/xbmc/cores/AudioEngine/AEResampleFactory.cpp
index 32d13c68da..224910f465 100644
--- a/xbmc/cores/AudioEngine/AEResampleFactory.cpp
+++ b/xbmc/cores/AudioEngine/AEResampleFactory.cpp
@@ -8,22 +8,12 @@
#include "AEResampleFactory.h"
#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h"
-#if defined(TARGET_RASPBERRY_PI)
- #include "ServiceBroker.h"
- #include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
- #include "cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h"
-#endif
namespace ActiveAE
{
IAEResample *CAEResampleFactory::Create(uint32_t flags /* = 0 */)
{
-#if defined(TARGET_RASPBERRY_PI)
- if (!(flags & AERESAMPLEFACTORY_QUICK_RESAMPLE) && CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_AUDIOOUTPUT_PROCESSQUALITY) == AE_QUALITY_GPU)
- return new CActiveAEResamplePi();
-#endif
return new CActiveAEResampleFFMPEG();
}
diff --git a/xbmc/cores/AudioEngine/CMakeLists.txt b/xbmc/cores/AudioEngine/CMakeLists.txt
index 3f97e30220..eb34be83a3 100644
--- a/xbmc/cores/AudioEngine/CMakeLists.txt
+++ b/xbmc/cores/AudioEngine/CMakeLists.txt
@@ -51,7 +51,7 @@ if(ALSA_FOUND)
Utils/AEELDParser.cpp)
list(APPEND HEADERS Sinks/AESinkALSA.h
Utils/AEELDParser.h)
-
+
if(NOT CORE_PLATFORM_NAME_LC STREQUAL x11)
list(APPEND SOURCES Sinks/alsa/ALSAHControlMonitor.cpp)
list(APPEND HEADERS Sinks/alsa/ALSAHControlMonitor.h)
@@ -94,13 +94,6 @@ if(CORE_SYSTEM_NAME MATCHES windows)
endif()
endif()
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- list(APPEND SOURCES Engines/ActiveAE/ActiveAEResamplePi.cpp
- Sinks/AESinkPi.cpp)
- list(APPEND HEADERS Engines/ActiveAE/ActiveAEResamplePi.h
- Sinks/AESinkPi.h)
-endif()
-
if(CORE_SYSTEM_NAME STREQUAL osx)
list(APPEND SOURCES Sinks/AESinkDARWINOSX.cpp
Sinks/darwin/CoreAudioHelpers.cpp
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
index a4b62e02fe..d9def8434c 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
@@ -2734,10 +2734,6 @@ bool CActiveAE::SupportsQualityLevel(enum AEQuality level)
{
if (level == AE_QUALITY_LOW || level == AE_QUALITY_MID || level == AE_QUALITY_HIGH)
return true;
-#if defined(TARGET_RASPBERRY_PI)
- if (level == AE_QUALITY_GPU)
- return true;
-#endif
return false;
}
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
deleted file mode 100644
index 00d0ad57a8..0000000000
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright (C) 2010-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include <cassert>
-
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "ActiveAEResamplePi.h"
-#include "settings/Settings.h"
-#include "utils/log.h"
-#include "platform/linux/RBP.h"
-
-extern "C" {
-#include <libavutil/channel_layout.h>
-#include <libavutil/opt.h>
-#include <libswresample/swresample.h>
-}
-
-//#define DEBUG_VERBOSE
-
-#define CLASSNAME "CActiveAEResamplePi"
-
-#define BUFFERSIZE (32*1024*2*8)
-
-//#define BENCHMARKING
-#ifdef BENCHMARKING
-#define LOGTIMEINIT(f) \
- struct timespec now; \
- uint64_t Start, End; \
- clock_gettime(CLOCK_MONOTONIC, &now); \
- Start = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \
- const char *_filename = f;
-
-#define LOGTIME(n) \
- clock_gettime(CLOCK_MONOTONIC, &now); \
- End = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \
- CLog::Log(LOGINFO, "ActiveAE::%s %d - resample %s took %.0fms", __FUNCTION__, n, _filename, \
- (End - Start) * 1e-6); \
- Start = End;
-#else
-#define LOGTIMEINIT(f)
-#define LOGTIME(n)
-#endif
-
-using namespace ActiveAE;
-
-CActiveAEResamplePi::CActiveAEResamplePi()
-{
- CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__);
-
- m_Initialized = false;
- m_encoded_buffer = NULL;
- m_offset = 0;
- m_ratio = 0.0;
-}
-
-CActiveAEResamplePi::~CActiveAEResamplePi()
-{
- CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__);
- DeInit();
-}
-
-void CActiveAEResamplePi::DeInit()
-{
- CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__);
- if (m_Initialized)
- {
- m_omx_mixer.FlushAll();
- m_omx_mixer.Deinitialize();
- m_Initialized = false;
- }
-}
-
-static int format_to_bits(AVSampleFormat fmt)
-{
- switch (fmt)
- {
- case AV_SAMPLE_FMT_U8:
- case AV_SAMPLE_FMT_U8P:
- return 8;
- case AV_SAMPLE_FMT_S16:
- case AV_SAMPLE_FMT_S16P:
- return 16;
- case AV_SAMPLE_FMT_S32:
- case AV_SAMPLE_FMT_S32P:
- case AV_SAMPLE_FMT_FLT:
- case AV_SAMPLE_FMT_FLTP:
- return 32;
- default:
- assert(0);
- }
- return 0;
-}
-
-bool CActiveAEResamplePi::Init(SampleConfig dstConfig, SampleConfig srcConfig, bool upmix, bool normalize, double centerMix,
- CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample)
-{
- LOGTIMEINIT("x");
-
- CLog::Log(LOGINFO,
- "%s::%s remap:%p chan:%d->%d rate:%d->%d format:%d->%d bits:%d->%d dither:%d->%d "
- "norm:%d upmix:%d",
- CLASSNAME, __func__, static_cast<void*>(remapLayout), srcConfig.channels, dstConfig.channels,
- srcConfig.sample_rate, dstConfig.sample_rate, srcConfig.fmt, dstConfig.fmt,
- srcConfig.bits_per_sample, dstConfig.bits_per_sample, srcConfig.dither_bits, dstConfig.dither_bits,
- normalize, upmix);
-
- m_dst_chan_layout = dstConfig.channel_layout;
- m_dst_channels = dstConfig.channels;
- m_dst_rate = dstConfig.sample_rate;
- m_dst_fmt = dstConfig.fmt;
- m_dst_bits = dstConfig.bits_per_sample;
- m_dst_dither_bits = dstConfig.dither_bits;
- m_src_chan_layout = srcConfig.channel_layout;
- m_src_channels = srcConfig.channels;
- m_src_rate = srcConfig.sample_rate;
- m_src_fmt = srcConfig.fmt;
- m_src_bits = srcConfig.bits_per_sample;
- m_src_dither_bits = srcConfig.dither_bits;
- m_offset = 0;
- m_src_pitch = format_to_bits(m_src_fmt) >> 3;
- m_dst_pitch = format_to_bits(m_dst_fmt) >> 3;
- m_force_resample = force_resample;
-
- // special handling for S24 formats which are carried in S32 (S24NE3)
- if ((m_dst_fmt == AV_SAMPLE_FMT_S32 || m_dst_fmt == AV_SAMPLE_FMT_S32P) && m_dst_bits == 24 && m_dst_dither_bits == -8)
- m_dst_pitch = 24;
-
- if (m_dst_chan_layout == 0)
- m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels);
- if (m_src_chan_layout == 0)
- m_src_chan_layout = av_get_default_channel_layout(m_src_channels);
-
- OMX_CONFIG_BRCMAUDIODOWNMIXCOEFFICIENTS8x8 mix;
- OMX_INIT_STRUCTURE(mix);
-
- assert(sizeof(mix.coeff)/sizeof(mix.coeff[0]) == 64);
-
- LOGTIME(1);
-// this code is just uses ffmpeg to produce the 8x8 mixing matrix
-{
- // dummy sample rate and format, as we only care about channel mapping
- SwrContext *m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, AV_SAMPLE_FMT_FLT, 48000,
- m_src_chan_layout, AV_SAMPLE_FMT_FLT, 48000, 0, NULL);
- if (!m_pContext)
- {
- CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - create context failed");
- return false;
- }
- // tell resampler to clamp float values
- // not required for sink stage (remapLayout == true)
- if (!remapLayout && normalize)
- {
- av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0);
- }
-
- if (remapLayout)
- {
- // one-to-one mapping of channels
- // remapLayout is the layout of the sink, if the channel is in our src layout
- // the channel is mapped by setting coef 1.0
- double m_rematrix[AE_CH_MAX][AE_CH_MAX];
- memset(m_rematrix, 0, sizeof(m_rematrix));
- m_dst_chan_layout = 0;
- for (unsigned int out=0; out<remapLayout->Count(); out++)
- {
- m_dst_chan_layout += (uint64_t) (1 << out);
- int idx = CAEUtil::GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout);
- if (idx >= 0)
- {
- m_rematrix[out][idx] = 1.0;
- }
- }
-
- av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0);
- av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0);
-
- if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0)
- {
- CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - setting channel matrix failed");
- return false;
- }
- }
- // stereo upmix
- else if (upmix && m_src_channels == 2 && m_dst_channels > 2)
- {
- double m_rematrix[AE_CH_MAX][AE_CH_MAX];
- memset(m_rematrix, 0, sizeof(m_rematrix));
- for (int out=0; out<m_dst_channels; out++)
- {
- uint64_t out_chan = av_channel_layout_extract_channel(m_dst_chan_layout, out);
- switch(out_chan)
- {
- case AV_CH_FRONT_LEFT:
- case AV_CH_BACK_LEFT:
- case AV_CH_SIDE_LEFT:
- m_rematrix[out][0] = 1.0;
- break;
- case AV_CH_FRONT_RIGHT:
- case AV_CH_BACK_RIGHT:
- case AV_CH_SIDE_RIGHT:
- m_rematrix[out][1] = 1.0;
- break;
- case AV_CH_FRONT_CENTER:
- m_rematrix[out][0] = 0.5;
- m_rematrix[out][1] = 0.5;
- break;
- case AV_CH_LOW_FREQUENCY:
- m_rematrix[out][0] = 0.5;
- m_rematrix[out][1] = 0.5;
- break;
- default:
- break;
- }
- }
-
- if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0)
- {
- CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - setting channel matrix failed");
- return false;
- }
- }
-
- if (swr_init(m_pContext) < 0)
- {
- CLog::Log(LOGERROR, "CActiveAEResamplePi::Init - init resampler failed");
- return false;
- }
-
- const int samples = 8;
- uint8_t *output, *input;
- av_samples_alloc(&output, NULL, m_dst_channels, samples, AV_SAMPLE_FMT_FLT, 1);
- av_samples_alloc(&input , NULL, m_src_channels, samples, AV_SAMPLE_FMT_FLT, 1);
-
- // Produce "identity" samples
- float *f = (float *)input;
- for (int j=0; j < samples; j++)
- for (int i=0; i < m_src_channels; i++)
- *f++ = i == j ? 1.0f : 0.0f;
-
- int ret = swr_convert(m_pContext, &output, samples, (const uint8_t **)&input, samples);
- if (ret < 0)
- CLog::Log(LOGERROR, "CActiveAEResamplePi::Resample - resample failed");
-
- f = (float *)output;
- for (int j=0; j < samples; j++)
- for (int i=0; i < m_dst_channels; i++)
- mix.coeff[8*i+j] = *f++ * (1<<16);
-
- for (int j=0; j < 8; j++)
- {
- char s[128] = {}, *t=s;
- for (int i=0; i < 8; i++)
- t += sprintf(t, "% 6.2f ", mix.coeff[j*8+i] * (1.0/0x10000));
- CLog::Log(LOGINFO, "%s::%s %s", CLASSNAME, __func__, s);
- }
- av_freep(&input);
- av_freep(&output);
- swr_free(&m_pContext);
-}
- LOGTIME(2);
-
- // This may be called before Application calls g_RBP.Initialise, so call it here too
- g_RBP.Initialize();
-
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if (!m_omx_mixer.Initialize("OMX.broadcom.audio_mixer", OMX_IndexParamAudioInit))
- CLog::Log(LOGERROR, "%s::%s - m_omx_mixer.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- LOGTIME(3);
-
- if (m_force_resample)
- {
- OMX_PARAM_U32TYPE scaleType;
- OMX_INIT_STRUCTURE(scaleType);
-
- scaleType.nPortIndex = m_omx_mixer.GetInputPort();
- scaleType.nU32 = (1 << 16);
- omx_err = m_omx_mixer.SetConfig(OMX_IndexParamBrcmTimeScale, &scaleType);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer Failed to set OMX_IndexParamBrcmTimeScale omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- m_ratio = 1.0;
- }
- // audio_mixer only supports up to 192kHz, however as long as ratio of samplerates remains the same we can lie
- while (srcConfig.sample_rate > 192000 || dstConfig.sample_rate > 192000)
- srcConfig.sample_rate >>= 1, dstConfig.sample_rate >>= 1;
-
- OMX_INIT_STRUCTURE(m_pcm_input);
- m_pcm_input.nPortIndex = m_omx_mixer.GetInputPort();
- m_pcm_input.eNumData = OMX_NumericalDataSigned;
- m_pcm_input.eEndian = OMX_EndianLittle;
- m_pcm_input.bInterleaved = OMX_TRUE;
- m_pcm_input.nBitPerSample = m_src_pitch << 3;
- // 0x8000 = float, 0x10000 = planar
- uint32_t flags = 0;
- if (m_src_fmt == AV_SAMPLE_FMT_FLT || m_src_fmt == AV_SAMPLE_FMT_FLTP)
- flags |= 0x8000;
- if (m_src_fmt >= AV_SAMPLE_FMT_U8P)
- flags |= 0x10000;
- m_pcm_input.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags;
- m_pcm_input.nChannels = srcConfig.channels;
- m_pcm_input.nSamplingRate = srcConfig.sample_rate;
-
- omx_err = m_omx_mixer.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer in SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- OMX_INIT_STRUCTURE(m_pcm_output);
- m_pcm_output.nPortIndex = m_omx_mixer.GetOutputPort();
- m_pcm_output.eNumData = OMX_NumericalDataSigned;
- m_pcm_output.eEndian = OMX_EndianLittle;
- m_pcm_output.bInterleaved = OMX_TRUE;
- m_pcm_output.nBitPerSample = m_dst_pitch << 3;
- flags = 0;
- if (m_dst_fmt == AV_SAMPLE_FMT_FLT || m_dst_fmt == AV_SAMPLE_FMT_FLTP)
- flags |= 0x8000;
- if (m_dst_fmt >= AV_SAMPLE_FMT_U8P)
- flags |= 0x10000;
- // shift bits if destination format requires it, swr_resamples aligns to the left
- if (m_dst_bits != 32 && (m_dst_dither_bits + m_dst_bits) != 32)
- flags |= (32 - m_dst_bits - m_dst_dither_bits) << 8;
-
- m_pcm_output.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags;
- m_pcm_output.nChannels = dstConfig.channels;
- m_pcm_output.nSamplingRate = dstConfig.sample_rate;
-
- omx_err = m_omx_mixer.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer out SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- LOGTIME(4);
-
- mix.nPortIndex = m_omx_mixer.GetInputPort();
- omx_err = m_omx_mixer.SetConfig(OMX_IndexConfigBrcmAudioDownmixCoefficients8x8, &mix);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(
- LOGERROR,
- "%s::%s - error setting mixer OMX_IndexConfigBrcmAudioDownmixCoefficients, error 0x%08x",
- CLASSNAME, __func__, omx_err);
- return false;
- }
-
- // set up the number/size of buffers for decoder input
- OMX_PARAM_PORTDEFINITIONTYPE port_param;
- OMX_INIT_STRUCTURE(port_param);
- port_param.nPortIndex = m_omx_mixer.GetInputPort();
-
- omx_err = m_omx_mixer.GetParameter(OMX_IndexParamPortDefinition, &port_param);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)1);
- port_param.nBufferSize = BUFFERSIZE;
-
- omx_err = m_omx_mixer.SetParameter(OMX_IndexParamPortDefinition, &port_param);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- LOGTIME(5);
-
- omx_err = m_omx_mixer.AllocInputBuffers();
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err);
-
- LOGTIME(6);
-
- // set up the number/size of buffers for decoder output
- OMX_INIT_STRUCTURE(port_param);
- port_param.nPortIndex = m_omx_mixer.GetOutputPort();
-
- omx_err = m_omx_mixer.GetParameter(OMX_IndexParamPortDefinition, &port_param);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)1);
- port_param.nBufferSize = BUFFERSIZE;
-
- omx_err = m_omx_mixer.SetParameter(OMX_IndexParamPortDefinition, &port_param);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- LOGTIME(7);
-
- omx_err = m_omx_mixer.AllocOutputBuffers();
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err);
-
- LOGTIME(8);
-
- omx_err = m_omx_mixer.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - m_omx_mixer OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- LOGTIME(9);
-
- m_Initialized = true;
-
- return true;
-}
-
-
-static void copy_planes(uint8_t **dst_buffer, int d_pitch, int d_planes, int d_samplesize, int offset, uint8_t *src_buffer, int src_samples, int planesize)
-{
- for (int i=0; i < d_planes; i++)
- memcpy(dst_buffer[i] + offset * d_pitch, src_buffer + i * planesize, src_samples * d_samplesize / d_planes);
-}
-
-int CActiveAEResamplePi::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio)
-{
- #ifdef DEBUG_VERBOSE
- CLog::Log(LOGINFO, "%s::%s samples:%d->%d (%.2f)", CLASSNAME, __func__, src_samples, dst_samples, ratio);
- #endif
- if (!m_Initialized)
- return 0;
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if (m_ratio != 0.0 && ratio != m_ratio)
- {
- OMX_PARAM_U32TYPE scaleType;
- OMX_INIT_STRUCTURE(scaleType);
-
- scaleType.nPortIndex = m_omx_mixer.GetInputPort();
- scaleType.nU32 = (1 << 16) / ratio;
- omx_err = m_omx_mixer.SetConfig(OMX_IndexParamBrcmTimeScale, &scaleType);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer Failed to set OMX_IndexParamBrcmTimeScale omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- m_ratio = ratio;
- }
-
- const int s_planes = m_src_fmt >= AV_SAMPLE_FMT_U8P ? m_src_channels : 1;
- const int d_planes = m_dst_fmt >= AV_SAMPLE_FMT_U8P ? m_dst_channels : 1;
- const int s_chans = m_src_fmt >= AV_SAMPLE_FMT_U8P ? 1 : m_src_channels;
- const int d_chans = m_dst_fmt >= AV_SAMPLE_FMT_U8P ? 1 : m_dst_channels;
- const int s_pitch = s_chans * m_src_pitch;
- const int d_pitch = d_chans * m_dst_pitch;
-
- const int s_samplesize = m_src_channels * m_src_pitch;
- const int d_samplesize = m_dst_channels * m_dst_pitch;
- const int max_src_samples = BUFFERSIZE / s_samplesize;
- const int max_dst_samples = (long long)(BUFFERSIZE / d_samplesize) * m_src_rate / (m_dst_rate + m_src_rate-1);
-
- int sent = 0;
- int received = 0;
-
- while (1)
- {
- if (m_encoded_buffer && m_encoded_buffer->nFilledLen)
- {
- int samples_available = m_encoded_buffer->nFilledLen / d_samplesize - m_offset;
- int samples = std::min(samples_available, dst_samples - received);
- copy_planes(dst_buffer, d_pitch, d_planes, d_samplesize, received, (uint8_t *)m_encoded_buffer->pBuffer + m_offset * d_pitch, samples, m_encoded_buffer->nFilledLen / d_planes);
- received += samples;
- m_offset += samples;
- if (m_offset == m_encoded_buffer->nFilledLen / d_samplesize)
- {
- m_offset = 0;
- m_encoded_buffer = NULL;
- }
- else if (m_offset > m_encoded_buffer->nFilledLen / d_samplesize) assert(0);
- else assert(sent == src_samples);
- }
-
- if (sent >= src_samples)
- break;
-
- OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_mixer.GetInputBuffer(1000);
- if (omx_buffer == NULL)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_mixer.GetInputBuffer failed to get buffer", CLASSNAME, __func__);
- return false;
- }
- int send = std::min(std::min(max_dst_samples, max_src_samples), src_samples - sent);
-
- omx_buffer->nOffset = 0;
- omx_buffer->nFlags = OMX_BUFFERFLAG_EOS;
- omx_buffer->nFilledLen = send * s_samplesize;
-
- assert(omx_buffer->nFilledLen > 0 && omx_buffer->nFilledLen <= omx_buffer->nAllocLen);
-
- if (omx_buffer->nFilledLen)
- {
- int planesize = omx_buffer->nFilledLen / s_planes;
- for (int i=0; i < s_planes; i++)
- memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, src_buffer[i] + sent * s_pitch, planesize);
- sent += send;
- }
-
- omx_err = m_omx_mixer.EmptyThisBuffer(omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s OMX_EmptyThisBuffer() failed with result(0x%x)", CLASSNAME, __func__, omx_err);
- m_omx_mixer.DecoderEmptyBufferDone(m_omx_mixer.GetComponent(), omx_buffer);
- return false;
- }
-
- m_encoded_buffer = m_omx_mixer.GetOutputBuffer();
-
- if (!m_encoded_buffer)
- {
- CLog::Log(LOGERROR, "%s::%s no output buffer", CLASSNAME, __func__);
- return false;
- }
- omx_err = m_omx_mixer.FillThisBuffer(m_encoded_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_mixer.FillThisBuffer result(0x%x)", CLASSNAME, __func__, omx_err);
- m_omx_mixer.DecoderFillBufferDone(m_omx_mixer.GetComponent(), m_encoded_buffer);
- return false;
- }
- omx_err = m_omx_mixer.WaitForOutputDone(1000);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_mixer.WaitForOutputDone result(0x%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
- assert(m_encoded_buffer->nFilledLen > 0 && m_encoded_buffer->nFilledLen <= m_encoded_buffer->nAllocLen);
-
- if (m_omx_mixer.BadState())
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_mixer.BadState", CLASSNAME, __func__);
- return false;
- }
- if (sent < src_samples)
- CLog::Log(LOGERROR, "%s::%s More data to send %d/%d", CLASSNAME, __func__, sent, src_samples);
- }
- #ifdef DEBUG_VERBOSE
- CLog::Log(LOGINFO, "%s::%s format:%d->%d rate:%d->%d chan:%d->%d samples %d->%d (%f) %d", CLASSNAME, __func__,
- (int)m_src_fmt, (int)m_dst_fmt, m_src_rate, m_dst_rate, m_src_channels, m_dst_channels, src_samples, dst_samples, ratio, received);
- #endif
- assert(received <= dst_samples);
- return received;
-}
-
-int64_t CActiveAEResamplePi::GetDelay(int64_t base)
-{
- int64_t ret = av_rescale_rnd(GetBufferedSamples(), m_dst_rate, base, AV_ROUND_UP);
-
- #ifdef DEBUG_VERBOSE
- CLog::Log(LOGINFO, "%s::%s = %" PRId64, CLASSNAME, __func__, ret);
- #endif
- return ret;
-}
-
-int CActiveAEResamplePi::GetBufferedSamples()
-{
- int samples = 0;
- if (m_encoded_buffer)
- {
- const int d_samplesize = m_dst_channels * m_src_pitch;
- samples = m_encoded_buffer->nFilledLen / d_samplesize - m_offset;
- }
- #ifdef DEBUG_VERBOSE
- CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, samples);
- #endif
- return samples;
-}
-
-int CActiveAEResamplePi::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate)
-{
- int ret = av_rescale_rnd(src_samples, dst_rate, src_rate, AV_ROUND_UP);
- #ifdef DEBUG_VERBOSE
- CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret);
- #endif
- return ret;
-}
-
-int CActiveAEResamplePi::GetSrcBufferSize(int samples)
-{
- int ret = av_samples_get_buffer_size(NULL, m_src_channels, samples, m_src_fmt, 1);
- #ifdef DEBUG_VERBOSE
- CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret);
- #endif
- return ret;
-}
-
-int CActiveAEResamplePi::GetDstBufferSize(int samples)
-{
- int ret = av_samples_get_buffer_size(NULL, m_dst_channels, samples, m_dst_fmt, 1);
- #ifdef DEBUG_VERBOSE
- CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret);
- #endif
- return ret;
-}
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h
deleted file mode 100644
index 8a6ad52ce1..0000000000
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010-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 "cores/AudioEngine/Interfaces/AEResample.h"
-
-#include "platform/linux/OMXCore.h"
-
-namespace ActiveAE
-{
-
-class CActiveAEResamplePi : public IAEResample
-{
-public:
- const char *GetName() { return "ActiveAEResamplePi"; }
- CActiveAEResamplePi();
- virtual ~CActiveAEResamplePi();
- bool Init(SampleConfig dstConfig, SampleConfig srcConfig, bool upmix, bool normalize, double centerMix,
- CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample);
- int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio);
- int64_t GetDelay(int64_t base);
- int GetBufferedSamples();
- bool WantsNewSamples(int samples) { return GetBufferedSamples() <= samples; }
- int CalcDstSampleCount(int src_samples, int dst_rate, int src_rate);
- int GetSrcBufferSize(int samples);
- int GetDstBufferSize(int samples);
-
-protected:
- void DeInit();
- uint64_t m_src_chan_layout, m_dst_chan_layout;
- int m_src_rate, m_dst_rate;
- int m_src_channels, m_dst_channels;
- AVSampleFormat m_src_fmt, m_dst_fmt;
- int m_src_bits, m_dst_bits;
- int m_src_pitch, m_dst_pitch;
- int m_src_dither_bits, m_dst_dither_bits;
-
- OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_input;
- OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_output;
- COMXCoreComponent m_omx_mixer;
- bool m_Initialized;
- bool m_force_resample;
- OMX_BUFFERHEADERTYPE *m_encoded_buffer;
- unsigned int m_offset;
- double m_ratio;
-};
-
-}
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
index 10efd5a43a..2a40dd47e8 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
@@ -1089,7 +1089,7 @@ void CAESinkAUDIOTRACK::UpdateAvailablePCMCapabilities()
}
if (m_sinkSupportsMultiChannelFloat)
{
- CLog::Log(LOGNOTICE, "Multi channel Float is supported");
+ CLog::Log(LOGINFO, "Multi channel Float is supported");
}
int test_sample[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp
deleted file mode 100644
index 7822c91fdb..0000000000
--- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * Copyright (C) 2010-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "AESinkPi.h"
-
-#include "ServiceBroker.h"
-#include "cores/AudioEngine/AESinkFactory.h"
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "utils/XTimeUtils.h"
-#include "utils/log.h"
-
-#include "platform/linux/RBP.h"
-
-#include <cassert>
-#include <limits.h>
-#include <stdint.h>
-
-#define CLASSNAME "CAESinkPi"
-
-#define NUM_OMX_BUFFERS 2
-#define AUDIO_PLAYBUFFER (0.1) // 100ms
-
-#ifdef OMX_SKIP64BIT
-static inline OMX_TICKS ToOMXTime(int64_t pts)
-{
- OMX_TICKS ticks;
- ticks.nLowPart = pts;
- ticks.nHighPart = pts >> 32;
- return ticks;
-}
-#else
-#define ToOMXTime(x) (x)
-#endif
-
-static const unsigned int PassthroughSampleRates[] = { 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
-
-CAEDeviceInfo CAESinkPi::m_info;
-
-CAESinkPi::CAESinkPi() :
- m_sinkbuffer_sec_per_byte(0),
- m_Initialized(false),
- m_submitted(0),
- m_omx_output(NULL),
- m_output(AESINKPI_UNKNOWN)
-{
-}
-
-CAESinkPi::~CAESinkPi()
-{
-}
-
-void CAESinkPi::SetAudioDest()
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest;
- OMX_INIT_STRUCTURE(audioDest);
- if ( m_omx_render.IsInitialized() )
- {
- if (m_output == AESINKPI_ANALOGUE)
- strncpy(reinterpret_cast<char*>(audioDest.sName), "local", strlen("local") + 1);
- else
- strncpy(reinterpret_cast<char*>(audioDest.sName), "hdmi", strlen("hdmi") + 1);
- omx_err = m_omx_render.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - m_omx_render.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
- if ( m_omx_render_slave.IsInitialized() )
- {
- if (m_output != AESINKPI_ANALOGUE)
- strncpy(reinterpret_cast<char*>(audioDest.sName), "local", strlen("local") + 1);
- else
- strncpy(reinterpret_cast<char*>(audioDest.sName), "hdmi", strlen("hdmi") + 1);
- omx_err = m_omx_render_slave.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - m_omx_render_slave.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
-}
-
-static void SetAudioProps(bool stream_channels, uint32_t channel_map)
-{
- char command[80], response[80];
-
- sprintf(command, "hdmi_stream_channels %d", stream_channels ? 1 : 0);
- vc_gencmd(response, sizeof response, command);
-
- sprintf(command, "hdmi_channel_map 0x%08x", channel_map);
- vc_gencmd(response, sizeof response, command);
-
- CLog::Log(LOGDEBUG, "%s:%s hdmi_stream_channels %d hdmi_channel_map %08x", CLASSNAME, __func__, stream_channels, channel_map);
-}
-
-static uint32_t GetChannelMap(const CAEChannelInfo &channelLayout, bool passthrough)
-{
- unsigned int channels = channelLayout.Count();
- uint32_t channel_map = 0;
- if (passthrough)
- return 0;
-
- static const unsigned char map_normal[] =
- {
- 0, //AE_CH_RAW ,
- 1, //AE_CH_FL
- 2, //AE_CH_FR
- 4, //AE_CH_FC
- 3, //AE_CH_LFE
- 7, //AE_CH_BL
- 8, //AE_CH_BR
- 1, //AE_CH_FLOC,
- 2, //AE_CH_FROC,
- 4, //AE_CH_BC,
- 5, //AE_CH_SL
- 6, //AE_CH_SR
- };
- static const unsigned char map_back[] =
- {
- 0, //AE_CH_RAW ,
- 1, //AE_CH_FL
- 2, //AE_CH_FR
- 4, //AE_CH_FC
- 3, //AE_CH_LFE
- 5, //AE_CH_BL
- 6, //AE_CH_BR
- 1, //AE_CH_FLOC,
- 2, //AE_CH_FROC,
- 4, //AE_CH_BC,
- 5, //AE_CH_SL
- 6, //AE_CH_SR
- };
- const unsigned char *map = map_normal;
- // According to CEA-861-D only RL and RR are known. In case of a format having SL and SR channels
- // but no BR BL channels, we use the wide map in order to open only the num of channels really
- // needed.
- if (channelLayout.HasChannel(AE_CH_BL) && !channelLayout.HasChannel(AE_CH_SL))
- map = map_back;
-
- for (unsigned int i = 0; i < channels; ++i)
- {
- AEChannel c = channelLayout[i];
- unsigned int chan = 0;
- if ((unsigned int)c < sizeof map_normal / sizeof *map_normal)
- chan = map[(unsigned int)c];
- if (chan > 0)
- channel_map |= (chan-1) << (3*i);
- }
- // These numbers are from Table 28 Audio InfoFrame Data byte 4 of CEA 861
- // and describe the speaker layout
- static const uint8_t cea_map[] = {
- 0xff, // 0
- 0xff, // 1
- 0x00, // 2.0
- 0x02, // 3.0
- 0x08, // 4.0
- 0x0a, // 5.0
- 0xff, // 6
- 0x12, // 7.0
- 0xff, // 8
- };
- static const uint8_t cea_map_lfe[] = {
- 0xff, // 0
- 0xff, // 1
- 0xff, // 2
- 0x01, // 2.1
- 0x03, // 3.1
- 0x09, // 4.1
- 0x0b, // 5.1
- 0xff, // 7
- 0x13, // 7.1
- };
- uint8_t cea = channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels];
- if (cea == 0xff)
- CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, channelLayout.HasChannel(AE_CH_LFE), channels);
-
- channel_map |= cea << 24;
-
- return channel_map;
-}
-
-void CAESinkPi::Register()
-{
- AE::AESinkRegEntry reg;
- reg.sinkName = "PI";
- reg.createFunc = CAESinkPi::Create;
- reg.enumerateFunc = CAESinkPi::EnumerateDevicesEx;
- AE::CAESinkFactory::RegisterSink(reg);
-}
-
-IAESink* CAESinkPi::Create(std::string &device, AEAudioFormat &desiredFormat)
-{
- IAESink *sink = new CAESinkPi();
- if (sink->Initialize(desiredFormat, device))
- return sink;
-
- delete sink;
- return nullptr;
-}
-
-
-bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device)
-{
- // This may be called before Application calls g_RBP.Initialise, so call it here too
- g_RBP.Initialize();
-
- /* if we are raw need to let gpu know */
- m_passthrough = format.m_dataFormat == AE_FMT_RAW;
-
- m_initDevice = device;
- m_initFormat = format;
-
- const std::string audioDevice = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_AUDIOOUTPUT_AUDIODEVICE);
-
- if (m_passthrough || audioDevice == "PI:HDMI")
- m_output = AESINKPI_HDMI;
- else if (audioDevice == "PI:Analogue")
- m_output = AESINKPI_ANALOGUE;
- else if (audioDevice == "PI:Both")
- m_output = AESINKPI_BOTH;
- else if (audioDevice == "Default")
- m_output = AESINKPI_HDMI;
- else assert(0);
-
- // analogue only supports stereo
- if (m_output == AESINKPI_ANALOGUE || m_output == AESINKPI_BOTH)
- format.m_channelLayout = AE_CH_LAYOUT_2_0;
-
- // setup for a 50ms sink feed from SoftAE
- if (format.m_dataFormat != AE_FMT_FLOATP && format.m_dataFormat != AE_FMT_FLOAT &&
- format.m_dataFormat != AE_FMT_S32NE && format.m_dataFormat != AE_FMT_S32NEP && format.m_dataFormat != AE_FMT_S32LE &&
- format.m_dataFormat != AE_FMT_S16NE && format.m_dataFormat != AE_FMT_S16NEP && format.m_dataFormat != AE_FMT_S16LE)
- format.m_dataFormat = AE_FMT_S16LE;
- unsigned int channels = format.m_channelLayout.Count();
- unsigned int sample_size = CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3;
- format.m_frameSize = sample_size * channels;
- format.m_sampleRate = std::max(8000U, std::min(192000U, format.m_sampleRate));
- format.m_frames = format.m_sampleRate * AUDIO_PLAYBUFFER / NUM_OMX_BUFFERS;
-
- m_format = format;
- m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate);
-
- CLog::Log(LOGDEBUG, "%s:%s Format:%d Channels:%d Samplerate:%d framesize:%d bufsize:%d bytes/s=%.2f dest=%s", CLASSNAME, __func__,
- m_format.m_dataFormat, channels, m_format.m_sampleRate, m_format.m_frameSize, m_format.m_frameSize * m_format.m_frames, 1.0/m_sinkbuffer_sec_per_byte,
- audioDevice.c_str());
-
- // magic value used when omxplayer is playing - want sink to be disabled
- if (m_passthrough && m_format.m_streamInfo.m_sampleRate == 16000)
- return true;
-
- SetAudioProps(m_passthrough, GetChannelMap(m_format.m_channelLayout, m_passthrough));
-
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if (!m_omx_render.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit))
- CLog::Log(LOGERROR, "%s::%s - m_omx_render.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- if (m_output == AESINKPI_BOTH)
- {
- if (!m_omx_splitter.Initialize("OMX.broadcom.audio_splitter", OMX_IndexParamAudioInit))
- CLog::Log(LOGERROR, "%s::%s - m_omx_splitter.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- if (!m_omx_render_slave.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit))
- CLog::Log(LOGERROR, "%s::%s - m_omx_render.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- m_omx_output = &m_omx_splitter;
- }
- else
- m_omx_output = &m_omx_render;
-
- SetAudioDest();
-
- OMX_INIT_STRUCTURE(m_pcm_input);
- m_pcm_input.eNumData = OMX_NumericalDataSigned;
- m_pcm_input.eEndian = OMX_EndianLittle;
- m_pcm_input.bInterleaved = OMX_TRUE;
- m_pcm_input.nBitPerSample = sample_size * 8;
- // 0x8000 = float, 0x10000 = planar
- uint32_t flags = 0;
- if (m_format.m_dataFormat == AE_FMT_FLOAT || m_format.m_dataFormat == AE_FMT_FLOATP)
- flags |= 0x8000;
- if (AE_IS_PLANAR(m_format.m_dataFormat))
- flags |= 0x10000;
- m_pcm_input.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags;
- m_pcm_input.nChannels = channels;
- m_pcm_input.nSamplingRate = m_format.m_sampleRate;
-
- if ( m_omx_splitter.IsInitialized() )
- {
- m_pcm_input.nPortIndex = m_omx_splitter.GetInputPort();
- omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- m_pcm_input.nPortIndex = m_omx_splitter.GetOutputPort();
- omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input);
- if(omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- m_pcm_input.nPortIndex = m_omx_splitter.GetOutputPort() + 1;
- omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input);
- if(omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
-
- if ( m_omx_render_slave.IsInitialized() )
- {
- m_pcm_input.nPortIndex = m_omx_render_slave.GetInputPort();
- omx_err = m_omx_render_slave.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_render_slave SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
-
- if ( m_omx_render.IsInitialized() )
- {
- m_pcm_input.nPortIndex = m_omx_render.GetInputPort();
- omx_err = m_omx_render.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s::%s - error m_omx_render SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
-
- if ( m_omx_output->IsInitialized() )
- {
- // set up the number/size of buffers for decoder input
- OMX_PARAM_PORTDEFINITIONTYPE port_param;
- OMX_INIT_STRUCTURE(port_param);
- port_param.nPortIndex = m_omx_output->GetInputPort();
-
- omx_err = m_omx_output->GetParameter(OMX_IndexParamPortDefinition, &port_param);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)NUM_OMX_BUFFERS);
- port_param.nBufferSize = ALIGN_UP(m_format.m_frameSize * m_format.m_frames, port_param.nBufferAlignment);
-
- omx_err = m_omx_output->SetParameter(OMX_IndexParamPortDefinition, &port_param);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
-
- omx_err = m_omx_output->AllocInputBuffers();
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err);
- }
-
- if ( m_omx_splitter.IsInitialized() )
- {
- m_omx_tunnel_splitter.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort(), &m_omx_render, m_omx_render.GetInputPort());
- omx_err = m_omx_tunnel_splitter.Establish();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter.Establish 0x%08x", omx_err);
- return false;
- }
-
- m_omx_tunnel_splitter_slave.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort() + 1, &m_omx_render_slave, m_omx_render_slave.GetInputPort());
- omx_err = m_omx_tunnel_splitter_slave.Establish();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter_slave.Establish 0x%08x", omx_err);
- return false;
- }
- }
-
- if ( m_omx_splitter.IsInitialized() )
- {
- omx_err = m_omx_splitter.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - m_omx_splitter OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
- if ( m_omx_render.IsInitialized() )
- {
- omx_err = m_omx_render.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - m_omx_render OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
- if ( m_omx_render_slave.IsInitialized() )
- {
- omx_err = m_omx_render_slave.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- CLog::Log(LOGERROR, "%s:%s - m_omx_render_slave OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- }
-
- m_Initialized = true;
- return true;
-}
-
-
-void CAESinkPi::Deinitialize()
-{
- CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__);
- SetAudioProps(false, 0);
-
- if ( m_omx_render.IsInitialized() )
- m_omx_render.IgnoreNextError(OMX_ErrorPortUnpopulated);
- if ( m_omx_render_slave.IsInitialized() )
- m_omx_render_slave.IgnoreNextError(OMX_ErrorPortUnpopulated);
-
- if ( m_omx_tunnel_splitter.IsInitialized() )
- m_omx_tunnel_splitter.Deestablish();
- if ( m_omx_tunnel_splitter_slave.IsInitialized() )
- m_omx_tunnel_splitter_slave.Deestablish();
-
- if ( m_omx_splitter.IsInitialized() )
- m_omx_splitter.FlushAll();
- if ( m_omx_render.IsInitialized() )
- m_omx_render.FlushAll();
- if ( m_omx_render_slave.IsInitialized() )
- m_omx_render_slave.FlushAll();
-
- if ( m_omx_splitter.IsInitialized() )
- m_omx_splitter.Deinitialize();
- if ( m_omx_render.IsInitialized() )
- m_omx_render.Deinitialize();
- if ( m_omx_render_slave.IsInitialized() )
- m_omx_render_slave.Deinitialize();
-
- m_Initialized = false;
-}
-
-bool CAESinkPi::IsCompatible(const AEAudioFormat &format, const std::string &device)
-{
- bool compatible =
- /* compare against the requested format and the real format */
- (m_initFormat.m_sampleRate == format.m_sampleRate || m_format.m_sampleRate == format.m_sampleRate ) &&
- (m_initFormat.m_dataFormat == format.m_dataFormat || m_format.m_dataFormat == format.m_dataFormat ) &&
- (m_initFormat.m_channelLayout == format.m_channelLayout || m_format.m_channelLayout == format.m_channelLayout) &&
- (m_initDevice == device);
- CLog::Log(LOGDEBUG, "%s:%s Format:%d Channels:%d Samplerate:%d = %d", CLASSNAME, __func__, format.m_dataFormat, format.m_channelLayout.Count(), format.m_sampleRate, compatible);
- return compatible;
-}
-
-void CAESinkPi::GetDelay(AEDelayStatus& status)
-{
- OMX_PARAM_U32TYPE param;
- OMX_INIT_STRUCTURE(param);
-
- if (!m_Initialized)
- {
- status.SetDelay(0);
- return;
- }
-
- param.nPortIndex = m_omx_render.GetInputPort();
-
- OMX_ERRORTYPE omx_err = m_omx_render.GetConfig(OMX_IndexConfigAudioRenderingLatency, &param);
-
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x",
- CLASSNAME, __func__, omx_err);
- }
- double sinkbuffer_seconds_to_empty = m_sinkbuffer_sec_per_byte * param.nU32 * m_format.m_frameSize;
- status.SetDelay(sinkbuffer_seconds_to_empty);
-}
-
-double CAESinkPi::GetCacheTotal()
-{
- return AUDIO_PLAYBUFFER;
-}
-
-unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset)
-{
- if (!m_Initialized || !m_omx_output || !frames)
- {
- KODI::TIME::Sleep(10);
- return frames;
- }
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- OMX_BUFFERHEADERTYPE *omx_buffer = NULL;
-
- unsigned int channels = m_format.m_channelLayout.Count();
- unsigned int sample_size = CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3;
- const int planes = AE_IS_PLANAR(m_format.m_dataFormat) ? channels : 1;
- const int chans = AE_IS_PLANAR(m_format.m_dataFormat) ? 1 : channels;
- const int pitch = chans * sample_size;
-
- AEDelayStatus status;
- GetDelay(status);
- double delay = status.GetDelay();
- if (delay <= 0.0 && m_submitted)
- CLog::Log(LOGINFO, "%s:%s Underrun (delay:%.2f frames:%d)", CLASSNAME, __func__, delay, frames);
-
- omx_buffer = m_omx_output->GetInputBuffer(1000);
- if (omx_buffer == NULL)
- {
- CLog::Log(LOGERROR, "CAESinkPi::AddPackets timeout");
- return 0;
- }
-
- omx_buffer->nFilledLen = frames * m_format.m_frameSize;
- // must be true
- assert(omx_buffer->nFilledLen <= omx_buffer->nAllocLen);
- omx_buffer->nTimeStamp = ToOMXTime(0);
- omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
-
- if (omx_buffer->nFilledLen)
- {
- int planesize = omx_buffer->nFilledLen / planes;
- for (int i=0; i < planes; i++)
- memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, data[i] + offset * pitch, planesize);
- }
- omx_err = m_omx_output->EmptyThisBuffer(omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s:%s frames=%d err=%x", CLASSNAME, __func__, frames, omx_err);
- m_omx_output->DecoderEmptyBufferDone(m_omx_output->GetComponent(), omx_buffer);
- }
- m_submitted++;
- GetDelay(status);
- delay = status.GetDelay();
- if (delay > AUDIO_PLAYBUFFER)
- KODI::TIME::Sleep(static_cast<int>(1000.0f * (delay - AUDIO_PLAYBUFFER)));
- return frames;
-}
-
-void CAESinkPi::Drain()
-{
- AEDelayStatus status;
- GetDelay(status);
- int delay = (int)(status.GetDelay() * 1000.0);
- if (delay)
- KODI::TIME::Sleep(delay);
- CLog::Log(LOGDEBUG, "%s:%s delay:%dms now:%dms", CLASSNAME, __func__, delay, (int)(status.GetDelay() * 1000.0));
-}
-
-void CAESinkPi::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
-{
- m_info.m_channels.Reset();
- m_info.m_dataFormats.clear();
- m_info.m_streamTypes.clear();
- m_info.m_sampleRates.clear();
-
- m_info.m_deviceType = AE_DEVTYPE_HDMI;
- m_info.m_deviceName = "HDMI";
- m_info.m_displayName = "HDMI";
- m_info.m_displayNameExtra = "";
- m_info.m_channels += AE_CH_FL;
- m_info.m_channels += AE_CH_FR;
- for (unsigned int i=0; i<sizeof PassthroughSampleRates/sizeof *PassthroughSampleRates; i++)
- m_info.m_sampleRates.push_back(PassthroughSampleRates[i]);
- m_info.m_dataFormats.push_back(AE_FMT_FLOAT);
- m_info.m_dataFormats.push_back(AE_FMT_S32NE);
- m_info.m_dataFormats.push_back(AE_FMT_S16NE);
- m_info.m_dataFormats.push_back(AE_FMT_S32LE);
- m_info.m_dataFormats.push_back(AE_FMT_S16LE);
- m_info.m_dataFormats.push_back(AE_FMT_FLOATP);
- m_info.m_dataFormats.push_back(AE_FMT_S32NEP);
- m_info.m_dataFormats.push_back(AE_FMT_S16NEP);
-
- m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_AC3);
- m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_EAC3);
- m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD_CORE);
- m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_2048);
- m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_1024);
- m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_512);
- m_info.m_dataFormats.push_back(AE_FMT_RAW);
-
- m_info.m_wantsIECPassthrough = true;
- list.push_back(m_info);
-
- m_info.m_channels.Reset();
- m_info.m_dataFormats.clear();
- m_info.m_streamTypes.clear();
- m_info.m_sampleRates.clear();
-
- m_info.m_deviceType = AE_DEVTYPE_PCM;
- m_info.m_deviceName = "Analogue";
- m_info.m_displayName = "Analogue";
- m_info.m_displayNameExtra = "";
- m_info.m_channels += AE_CH_FL;
- m_info.m_channels += AE_CH_FR;
- m_info.m_sampleRates.push_back(48000);
- m_info.m_dataFormats.push_back(AE_FMT_FLOAT);
- m_info.m_dataFormats.push_back(AE_FMT_S32LE);
- m_info.m_dataFormats.push_back(AE_FMT_S16LE);
- m_info.m_dataFormats.push_back(AE_FMT_FLOATP);
- m_info.m_dataFormats.push_back(AE_FMT_S32NEP);
- m_info.m_dataFormats.push_back(AE_FMT_S16NEP);
-
- m_info.m_wantsIECPassthrough = true;
- list.push_back(m_info);
-
- m_info.m_channels.Reset();
- m_info.m_dataFormats.clear();
- m_info.m_streamTypes.clear();
- m_info.m_sampleRates.clear();
-
- m_info.m_deviceType = AE_DEVTYPE_PCM;
- m_info.m_deviceName = "Both";
- m_info.m_displayName = "HDMI and Analogue";
- m_info.m_displayNameExtra = "";
- m_info.m_channels += AE_CH_FL;
- m_info.m_channels += AE_CH_FR;
- m_info.m_sampleRates.push_back(48000);
- m_info.m_dataFormats.push_back(AE_FMT_FLOAT);
- m_info.m_dataFormats.push_back(AE_FMT_S32LE);
- m_info.m_dataFormats.push_back(AE_FMT_S16LE);
- m_info.m_dataFormats.push_back(AE_FMT_FLOATP);
- m_info.m_dataFormats.push_back(AE_FMT_S32NEP);
- m_info.m_dataFormats.push_back(AE_FMT_S16NEP);
-
- m_info.m_wantsIECPassthrough = true;
- list.push_back(m_info);
-}
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.h b/xbmc/cores/AudioEngine/Sinks/AESinkPi.h
deleted file mode 100644
index 3003bf90a9..0000000000
--- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010-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 "cores/AudioEngine/Interfaces/AESink.h"
-#include "cores/AudioEngine/Utils/AEDeviceInfo.h"
-#include "utils/XTimeUtils.h"
-
-#include "platform/linux/OMXCore.h"
-
-class CAESinkPi : public IAESink
-{
-public:
- virtual const char *GetName() { return "SinkPi"; }
-
- CAESinkPi();
- virtual ~CAESinkPi();
-
- static void Register();
- static IAESink* Create(std::string &device, AEAudioFormat &desiredFormat);
-
- virtual bool Initialize(AEAudioFormat &format, std::string &device);
- virtual void Deinitialize();
- virtual bool IsCompatible(const AEAudioFormat &format, const std::string &device);
-
- virtual void GetDelay (AEDelayStatus& status);
- virtual double GetCacheTotal ();
- virtual unsigned int AddPackets (uint8_t **data, unsigned int frames, unsigned int offset);
- virtual void Drain ();
-
- static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
-private:
- void SetAudioDest();
-
- std::string m_initDevice;
- AEAudioFormat m_initFormat;
- AEAudioFormat m_format;
- double m_sinkbuffer_sec_per_byte;
- static CAEDeviceInfo m_info;
- bool m_Initialized;
- uint32_t m_submitted;
- OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_input;
- COMXCoreComponent *m_omx_output;
- COMXCoreComponent m_omx_splitter;
- COMXCoreComponent m_omx_render;
- COMXCoreComponent m_omx_render_slave;
- bool m_passthrough;
- COMXCoreTunnel m_omx_tunnel_splitter;
- COMXCoreTunnel m_omx_tunnel_splitter_slave;
- enum { AESINKPI_UNKNOWN, AESINKPI_HDMI, AESINKPI_ANALOGUE, AESINKPI_BOTH } m_output;
-};
diff --git a/xbmc/cores/RetroPlayer/process/rbpi/CMakeLists.txt b/xbmc/cores/RetroPlayer/process/rbpi/CMakeLists.txt
deleted file mode 100644
index 97eb97960f..0000000000
--- a/xbmc/cores/RetroPlayer/process/rbpi/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- set(SOURCES RPProcessInfoPi.cpp)
-
- set(HEADERS RPProcessInfoPi.h)
-
- core_add_library(rp-process-pi)
-endif()
diff --git a/xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.cpp b/xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.cpp
deleted file mode 100644
index 135172979a..0000000000
--- a/xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-#include "RPProcessInfoPi.h"
-
-using namespace KODI;
-using namespace RETRO;
-
-CRPProcessInfoPi::CRPProcessInfoPi() : CRPProcessInfo("RPi")
-{
-}
-
-CRPProcessInfo* CRPProcessInfoPi::Create()
-{
- return new CRPProcessInfoPi();
-}
-
-void CRPProcessInfoPi::Register()
-{
- CRPProcessInfo::RegisterProcessControl(CRPProcessInfoPi::Create);
-}
diff --git a/xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.h b/xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.h
deleted file mode 100644
index a800f72bbb..0000000000
--- a/xbmc/cores/RetroPlayer/process/rbpi/RPProcessInfoPi.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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 "cores/RetroPlayer/process/RPProcessInfo.h"
-
-namespace KODI
-{
-namespace RETRO
-{
-class CRPProcessInfoPi : public CRPProcessInfo
-{
-public:
- CRPProcessInfoPi();
-
- static CRPProcessInfo* Create();
- static void Register();
-};
-} // namespace RETRO
-} // namespace KODI
diff --git a/xbmc/cores/VideoPlayer/Buffers/CMakeLists.txt b/xbmc/cores/VideoPlayer/Buffers/CMakeLists.txt
index 8fc7f3011c..a7db7f4de2 100644
--- a/xbmc/cores/VideoPlayer/Buffers/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/Buffers/CMakeLists.txt
@@ -1,7 +1,7 @@
set(SOURCES VideoBuffer.cpp)
set(HEADERS VideoBuffer.h)
-if(CORE_PLATFORM_NAME_LC STREQUAL gbm)
+if(CORE_PLATFORM_NAME_LC STREQUAL gbm OR CORE_PLATFORM_NAME_LC STREQUAL wayland)
list(APPEND SOURCES VideoBufferDMA.cpp
VideoBufferDRMPRIME.cpp
VideoBufferPoolDMA.cpp)
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/CMakeLists.txt b/xbmc/cores/VideoPlayer/DVDCodecs/Video/CMakeLists.txt
index f7b5513136..c91c19ff55 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/CMakeLists.txt
@@ -31,19 +31,12 @@ if(APPLE)
list(APPEND HEADERS VTB.h)
endif()
-if(MMAL_FOUND)
- list(APPEND SOURCES MMALCodec.cpp)
- list(APPEND HEADERS MMALCodec.h)
- list(APPEND SOURCES MMALFFmpeg.cpp)
- list(APPEND HEADERS MMALFFmpeg.h)
-endif()
-
if(CORE_SYSTEM_NAME STREQUAL android)
list(APPEND SOURCES DVDVideoCodecAndroidMediaCodec.cpp)
list(APPEND HEADERS DVDVideoCodecAndroidMediaCodec.h)
endif()
-if(CORE_PLATFORM_NAME_LC STREQUAL gbm)
+if(CORE_PLATFORM_NAME_LC STREQUAL gbm OR CORE_PLATFORM_NAME_LC STREQUAL wayland)
list(APPEND SOURCES DVDVideoCodecDRMPRIME.cpp)
list(APPEND HEADERS DVDVideoCodecDRMPRIME.h)
endif()
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
index 761a70470d..597b851c08 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
@@ -897,7 +897,7 @@ bool CDVDVideoCodecAndroidMediaCodec::AddData(const DemuxPacket &packet)
size_t out_size = buffer.capacity();
if ((size_t)iSize > out_size)
{
- CLog::Log(LOGNOTICE, "CDVDVideoCodecAndroidMediaCodec::AddData: iSize(%d) > size(%d)",
+ CLog::Log(LOGINFO, "CDVDVideoCodecAndroidMediaCodec::AddData: iSize(%d) > size(%d)",
iSize, out_size);
iSize = out_size;
}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
index ba3c93d89d..9e6521491c 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
@@ -19,7 +19,10 @@
#include "threads/SingleLock.h"
#include "utils/CPUInfo.h"
#include "utils/log.h"
+
+#if defined(HAVE_GBM)
#include "windowing/gbm/WinSystemGbm.h"
+#endif
extern "C"
{
@@ -30,8 +33,6 @@ extern "C"
#include <libavutil/pixdesc.h>
}
-using namespace KODI::WINDOWING::GBM;
-
namespace
{
@@ -242,13 +243,49 @@ bool CDVDVideoCodecDRMPRIME::Open(CDVDStreamInfo& hints, CDVDCodecOptions& optio
if (pConfig && (pConfig->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) &&
pConfig->device_type == AV_HWDEVICE_TYPE_DRM)
{
- CWinSystemGbm* winSystem = dynamic_cast<CWinSystemGbm*>(CServiceBroker::GetWinSystem());
- if (av_hwdevice_ctx_create(&m_pCodecContext->hw_device_ctx, AV_HWDEVICE_TYPE_DRM,
- drmGetDeviceNameFromFd2(winSystem->GetDrm()->GetFileDescriptor()),
- nullptr, 0) < 0)
+ const char* device = nullptr;
+
+ if (getenv("KODI_RENDER_NODE"))
+ device = getenv("KODI_RENDER_NODE");
+
+#if defined(HAVE_GBM)
+ auto winSystem = dynamic_cast<KODI::WINDOWING::GBM::CWinSystemGbm*>(CServiceBroker::GetWinSystem());
+
+ if (!winSystem)
+ return false;
+
+ auto drm = winSystem->GetDrm();
+
+ if (!drm)
+ return false;
+
+ int fd = drm->GetFileDescriptor();
+
+ if (fd < 0)
+ return false;
+
+ if (!device)
+ device = drmGetRenderDeviceNameFromFd(fd);
+
+ if (!device)
+ device = drmGetDeviceNameFromFd2(fd);
+
+ if (!device)
+ device = drmGetDeviceNameFromFd(fd);
+#endif
+
+ //! @todo: fix with proper device when dma-hints wayland protocol works
+ if (!device)
+ device = "/dev/dri/renderD128";
+
+ CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::{} - using drm device for av_hwdevice_ctx: {}", __FUNCTION__, device);
+
+ if (av_hwdevice_ctx_create(&m_pCodecContext->hw_device_ctx, pConfig->device_type,
+ device, nullptr, 0) < 0)
{
- CLog::Log(LOGINFO, "CDVDVideoCodecDRMPRIME::{} - unable to create hwdevice context",
- __FUNCTION__);
+ CLog::Log(LOGERROR,
+ "CDVDVideoCodecDRMPRIME::{} - unable to create hwdevice context using device: {}",
+ __FUNCTION__, device);
avcodec_free_context(&m_pCodecContext);
return false;
}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.cpp
deleted file mode 100644
index 4fdd733026..0000000000
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.cpp
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * Copyright (C) 2010-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.
- */
-
-#if defined(TARGET_WINDOWS)
-#endif
-
-#include <interface/mmal/util/mmal_util.h>
-#include <interface/mmal/util/mmal_default_components.h>
-#include <interface/mmal/util/mmal_util_params.h>
-
-#include "MMALCodec.h"
-
-#include "ServiceBroker.h"
-#include "DVDClock.h"
-#include "DVDStreamInfo.h"
-#include "cores/VideoPlayer/DVDCodecs/DVDCodecs.h"
-#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
-#include "DVDVideoCodec.h"
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-#include "settings/MediaSettings.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "messaging/ApplicationMessenger.h"
-#include "Application.h"
-#include "guilib/GUIWindowManager.h"
-#include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
-#include "settings/DisplaySettings.h"
-#include "settings/SettingsComponent.h"
-#include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
-#include "cores/VideoPlayer/Interface/Addon/TimingConstants.h"
-
-#include "platform/linux/RBP.h"
-
-using namespace KODI::MESSAGING;
-using namespace MMAL;
-
-#define CLASSNAME "CMMALVideoBuffer"
-
-#define VERBOSE 0
-
-CMMALVideoBuffer::CMMALVideoBuffer(int id) : CMMALBuffer(id)
-{
-}
-
-CMMALVideoBuffer::~CMMALVideoBuffer()
-{
-}
-
-#undef CLASSNAME
-#define CLASSNAME "CMMALVideo"
-
-CMMALVideo::CMMALVideo(CProcessInfo &processInfo) : CDVDVideoCodec(processInfo)
-{
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %p", CLASSNAME, __func__, static_cast<void*>(this));
-
- m_decoded_width = 0;
- m_decoded_height = 0;
- m_decoded_aligned_width = 0;
- m_decoded_aligned_height = 0;
-
- m_finished = false;
- m_pFormatName = "mmal-xxxx";
-
- m_interlace_mode = MMAL_InterlaceProgressive;
- m_decoderPts = DVD_NOPTS_VALUE;
- m_demuxerPts = DVD_NOPTS_VALUE;
-
- m_dec = NULL;
- m_dec_input = NULL;
- m_dec_output = NULL;
- m_dec_input_pool = NULL;
- m_pool = nullptr;
-
- m_codingType = 0;
-
- m_es_format = mmal_format_alloc();
- m_preroll = true;
- m_speed = DVD_PLAYSPEED_NORMAL;
- m_fps = 0.0f;
- m_num_decoded = 0;
- m_codecControlFlags = 0;
- m_got_eos = false;
- m_packet_num = 0;
- m_packet_num_eos = ~0;
-}
-
-CMMALVideo::~CMMALVideo()
-{
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %p", CLASSNAME, __func__, static_cast<void*>(this));
- if (!m_finished)
- Dispose();
-
- CSingleLock lock(m_sharedSection);
-
- if (m_dec && m_dec->control && m_dec->control->is_enabled)
- mmal_port_disable(m_dec->control);
-
- if (m_dec_input && m_dec_input->is_enabled)
- mmal_port_disable(m_dec_input);
-
- m_dec_output = NULL;
-
- if (m_dec_input_pool)
- mmal_port_pool_destroy(m_dec_input, m_dec_input_pool);
- m_dec_input_pool = NULL;
- m_dec_input = NULL;
-
- m_dec = NULL;
- mmal_format_free(m_es_format);
- m_es_format = NULL;
-}
-
-void CMMALVideo::PortSettingsChanged(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CSingleLock lock(m_sharedSection);
- MMAL_EVENT_FORMAT_CHANGED_T *fmt = mmal_event_format_changed_get(buffer);
- mmal_format_copy(m_es_format, fmt->format);
-
- if (m_es_format->es->video.crop.width && m_es_format->es->video.crop.height)
- {
- if (m_es_format->es->video.par.num && m_es_format->es->video.par.den)
- m_aspect_ratio = (float)(m_es_format->es->video.par.num * m_es_format->es->video.crop.width) / (m_es_format->es->video.par.den * m_es_format->es->video.crop.height);
- m_decoded_width = m_es_format->es->video.crop.width;
- m_decoded_height = m_es_format->es->video.crop.height;
- m_decoded_aligned_width = m_es_format->es->video.width;
- m_decoded_aligned_height = m_es_format->es->video.height;
-
- m_processInfo.SetVideoDimensions(m_decoded_width, m_decoded_height);
- m_processInfo.SetVideoDAR(m_aspect_ratio);
-
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s format changed: %dx%d (%dx%d) %.2f", CLASSNAME, __func__, m_decoded_width, m_decoded_height, m_decoded_aligned_width, m_decoded_aligned_height, m_aspect_ratio);
- }
- else
- CLog::Log(LOGERROR, "%s::%s format changed: Unexpected %dx%d (%dx%d)", CLASSNAME, __func__, m_es_format->es->video.crop.width, m_es_format->es->video.crop.height, m_decoded_aligned_width, m_decoded_aligned_height);
-
- if (!change_dec_output_format())
- CLog::Log(LOGERROR, "%s::%s - change_dec_output_format() failed", CLASSNAME, __func__);
-}
-
-void CMMALVideo::dec_control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- MMAL_STATUS_T status;
-
- if (buffer->cmd == MMAL_EVENT_ERROR)
- {
- status = (MMAL_STATUS_T)*(uint32_t *)buffer->data;
- CLog::Log(LOGERROR, "%s::%s Error (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- }
- else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED)
- {
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s format changed", CLASSNAME, __func__);
- PortSettingsChanged(port, buffer);
- }
- else
- CLog::Log(LOGERROR, "%s::%s other (cmd:%x data:%x)", CLASSNAME, __func__, buffer->cmd, *(uint32_t *)buffer->data);
-
- mmal_buffer_header_release(buffer);
-}
-
-static void dec_control_port_cb_static(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CMMALVideo *mmal = reinterpret_cast<CMMALVideo*>(port->userdata);
- mmal->dec_control_port_cb(port, buffer);
-}
-
-
-void CMMALVideo::dec_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s port:%p buffer %p, len %d cmd:%x", CLASSNAME, __func__,
- static_cast<void*>(port), static_cast<void*>(buffer), buffer->length, buffer->cmd);
- mmal_buffer_header_release(buffer);
- CSingleLock output_lock(m_output_mutex);
- m_output_cond.notifyAll();
-}
-
-static void dec_input_port_cb_static(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CMMALVideo *mmal = reinterpret_cast<CMMALVideo*>(port->userdata);
- mmal->dec_input_port_cb(port, buffer);
-}
-
-
-void CMMALVideo::dec_output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- if (!(buffer->cmd == 0 && buffer->length > 0))
- {
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s port:%p buffer %p, len %d cmd:%x flags:%x", CLASSNAME,
- __func__, static_cast<void*>(port), static_cast<void*>(buffer), buffer->length,
- buffer->cmd, buffer->flags);
- }
-
- bool kept = false;
- CMMALVideoBuffer *omvb = (CMMALVideoBuffer *)buffer->user_data;
-
- assert(!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED));
- if (buffer->cmd == 0)
- {
- if (buffer->length > 0)
- {
- if (buffer->pts != MMAL_TIME_UNKNOWN)
- m_decoderPts = buffer->pts;
- else if (buffer->dts != MMAL_TIME_UNKNOWN)
- m_decoderPts = buffer->dts;
-
- assert(!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_DECODEONLY));
- assert(omvb);
- assert(omvb->mmal_buffer == buffer);
- bool wanted = true;
- // we don't keep up when running at 60fps in the background so switch to half rate
- if (m_fps > 40.0f && !CServiceBroker::GetWinSystem()->GetGfxContext().IsFullScreenVideo() && !(m_num_decoded & 1))
- wanted = false;
- if ((buffer->flags & MMAL_BUFFER_HEADER_FLAG_CORRUPTED))
- wanted = false;
- m_num_decoded++;
- CLog::Log(LOGDEBUG, LOGVIDEO,
- "%s::%s - omvb:%p mmal:%p len:%u dts:%.3f pts:%.3f flags:%x:%x pool:%p %dx%d "
- "(%dx%d) %dx%d (%dx%d) enc:%.4s",
- CLASSNAME, __func__, static_cast<void*>(buffer), static_cast<void*>(omvb),
- buffer->length, buffer->dts * 1e-6, buffer->pts * 1e-6, buffer->flags,
- buffer->type->video.flags, static_cast<void*>(m_pool.get()), omvb->Width(),
- omvb->Height(), omvb->AlignedWidth(), omvb->AlignedHeight(), m_decoded_width,
- m_decoded_height, m_decoded_aligned_width, m_decoded_aligned_height,
- (char*)&omvb->Encoding());
- if (wanted)
- {
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- if (pool)
- pool->Configure(AV_PIX_FMT_NONE, m_decoded_width, m_decoded_height, m_decoded_aligned_width, m_decoded_aligned_height, 128);
- omvb->m_aspect_ratio = m_aspect_ratio;
- {
- CSingleLock output_lock(m_output_mutex);
- m_output_ready.push(omvb);
- m_output_cond.notifyAll();
- }
- kept = true;
- }
- }
- if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS)
- {
- CSingleLock output_lock(m_output_mutex);
- m_got_eos = true;
- m_output_cond.notifyAll();
- }
- }
- else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED)
- {
- PortSettingsChanged(port, buffer);
- }
- if (!kept)
- {
- if (omvb)
- omvb->Release();
- else
- mmal_buffer_header_release(buffer);
- }
-}
-
-static void dec_output_port_cb_static(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CMMALVideo *mmal = reinterpret_cast<CMMALVideo*>(port->userdata);
- mmal->dec_output_port_cb(port, buffer);
-}
-
-bool CMMALVideo::change_dec_output_format()
-{
- CSingleLock lock(m_sharedSection);
- MMAL_STATUS_T status;
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s", CLASSNAME, __func__);
-
- MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type = {{ MMAL_PARAMETER_VIDEO_INTERLACE_TYPE, sizeof( interlace_type )}};
- status = mmal_port_parameter_get( m_dec_output, &interlace_type.hdr );
-
- if (status == MMAL_SUCCESS)
- {
- if (m_interlace_mode != interlace_type.eMode)
- {
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s Interlace mode %d->%d", CLASSNAME, __func__, m_interlace_mode, interlace_type.eMode);
- m_interlace_mode = interlace_type.eMode;
- }
- }
- else
- CLog::Log(LOGERROR, "%s::%s Failed to query interlace type on %s (status=%x %s)", CLASSNAME, __func__, m_dec_output->name, status, mmal_status_to_string(status));
-
- mmal_format_copy(m_dec_output->format, m_es_format);
-
- status = mmal_port_parameter_set_boolean(m_dec_output, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_dec_output->name, status, mmal_status_to_string(status));
-
- status = mmal_port_format_commit(m_dec_output);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to commit decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- return true;
-}
-
-bool CMMALVideo::SendCodecConfigData()
-{
- CSingleLock lock(m_sharedSection);
- MMAL_STATUS_T status;
- if (!m_dec_input_pool || !m_hints.extrasize)
- return true;
- // send code config data
- MMAL_BUFFER_HEADER_T *buffer = mmal_queue_timedwait(m_dec_input_pool->queue, 500);
- if (!buffer)
- {
- CLog::Log(LOGERROR, "%s::%s - mmal_queue_get failed", CLASSNAME, __func__);
- return false;
- }
-
- mmal_buffer_header_reset(buffer);
- buffer->cmd = 0;
- buffer->length = std::min(m_hints.extrasize, buffer->alloc_size);
- memcpy(buffer->data, m_hints.extradata, buffer->length);
- buffer->flags = MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_CONFIG;
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - %-8p %-6d flags:%x", CLASSNAME, __func__, static_cast<void*>(buffer),
- buffer->length, buffer->flags);
- status = mmal_port_send_buffer(m_dec_input, buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed send buffer to decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- return true;
-}
-
-bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
-{
- CSingleLock lock(m_sharedSection);
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s usemmal:%d options:%x %dx%d", CLASSNAME, __func__, CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOPLAYER_USEMMAL), hints.codecOptions, hints.width, hints.height);
-
- // This occurs at start of m2ts files before streams have been fully identified - just ignore
- if (!hints.width)
- return false;
- // we always qualify even if DVDFactoryCodec does this too.
- if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOPLAYER_USEMMAL) || (hints.codecOptions & CODEC_FORCE_SOFTWARE))
- return false;
-
- std::list<EINTERLACEMETHOD> deintMethods;
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_AUTO);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_ADVANCED);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_BOB);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_BOB_HALF);
- m_processInfo.UpdateDeinterlacingMethods(deintMethods);
-
- m_hints = hints;
- MMAL_STATUS_T status;
-
- m_decoded_width = hints.width;
- m_decoded_height = hints.height;
-
- m_decoded_aligned_width = ALIGN_UP(m_decoded_width, 32);
- m_decoded_aligned_height = ALIGN_UP(m_decoded_height, 16);
-
- // use aspect in stream if available
- if (m_hints.forced_aspect)
- m_aspect_ratio = m_hints.aspect;
- else
- m_aspect_ratio = 0.0;
-
- switch (hints.codec)
- {
- case AV_CODEC_ID_H264:
- // H.264
- switch (hints.profile)
- {
- // Cannot hardware decode Hi10P without artifacts - switch to software on Pi2/Pi3
- case FF_PROFILE_H264_HIGH_10:
- case FF_PROFILE_H264_HIGH_10_INTRA:
- if (g_RBP.RaspberryPiVersion() > 1)
- return false;
- }
- m_codingType = MMAL_ENCODING_H264;
- m_pFormatName = "mmal-h264";
- if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOPLAYER_SUPPORTMVC))
- {
- m_codingType = MMAL_ENCODING_MVC;
- m_pFormatName= "mmal-mvc";
- }
- break;
- case AV_CODEC_ID_H263:
- case AV_CODEC_ID_MPEG4:
- // MPEG-4, DivX 4/5 and Xvid compatible
- m_codingType = MMAL_ENCODING_MP4V;
- m_pFormatName = "mmal-mpeg4";
- break;
- case AV_CODEC_ID_MPEG1VIDEO:
- case AV_CODEC_ID_MPEG2VIDEO:
- // MPEG-2
- m_codingType = MMAL_ENCODING_MP2V;
- m_pFormatName = "mmal-mpeg2";
- break;
- case AV_CODEC_ID_VP6:
- // this form is encoded upside down
- // fall through
- case AV_CODEC_ID_VP6F:
- case AV_CODEC_ID_VP6A:
- // VP6
- m_codingType = MMAL_ENCODING_VP6;
- m_pFormatName = "mmal-vp6";
- break;
- case AV_CODEC_ID_VP8:
- // VP8
- m_codingType = MMAL_ENCODING_VP8;
- m_pFormatName = "mmal-vp8";
- break;
- case AV_CODEC_ID_THEORA:
- // theora
- m_codingType = MMAL_ENCODING_THEORA;
- m_pFormatName = "mmal-theora";
- break;
- case AV_CODEC_ID_MJPEG:
- case AV_CODEC_ID_MJPEGB:
- // mjpg
- m_codingType = MMAL_ENCODING_MJPEG;
- m_pFormatName = "mmal-mjpg";
- break;
- case AV_CODEC_ID_VC1:
- case AV_CODEC_ID_WMV3:
- // VC-1, WMV9
- m_codingType = MMAL_ENCODING_WVC1;
- m_pFormatName = "mmal-vc1";
- break;
- default:
- CLog::Log(LOGERROR, "%s::%s : Video codec unknown: %x", CLASSNAME, __func__, hints.codec);
- return false;
- break;
- }
-
- if ( (m_codingType == MMAL_ENCODING_MP2V && !g_RBP.GetCodecMpg2() ) ||
- (m_codingType == MMAL_ENCODING_WVC1 && !g_RBP.GetCodecWvc1() ) )
- {
- CLog::Log(LOGWARNING, "%s::%s Codec %s is not supported", CLASSNAME, __func__, m_pFormatName);
- return false;
- }
-
- /* Create video component with attached pool */
- m_pool = std::make_shared<CMMALPool>(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, false, MMAL_NUM_OUTPUT_BUFFERS, 128, MMAL_ENCODING_OPAQUE, MMALStateHWDec);
- if (!m_pool)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to create pool for video output", CLASSNAME, __func__);
- return false;
- }
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- pool->SetProcessInfo(&m_processInfo);
- m_dec = pool->GetComponent();
-
- m_dec->control->userdata = (struct MMAL_PORT_USERDATA_T *)this;
- status = mmal_port_enable(m_dec->control, dec_control_port_cb_static);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable decoder control port %s (status=%x %s)", CLASSNAME, __func__, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status));
- return false;
- }
-
- m_dec_input = m_dec->input[0];
-
- m_dec_input->format->type = MMAL_ES_TYPE_VIDEO;
- m_dec_input->format->encoding = m_codingType;
- if (m_decoded_width && m_decoded_height)
- {
- m_dec_input->format->es->video.crop.width = m_decoded_width;
- m_dec_input->format->es->video.crop.height = m_decoded_height;
-
- m_dec_input->format->es->video.width = m_decoded_aligned_width;
- m_dec_input->format->es->video.height = m_decoded_aligned_width;
- }
- if (hints.fpsrate > 0 && hints.fpsscale > 0)
- {
- m_dec_input->format->es->video.frame_rate.num = hints.fpsrate;
- m_dec_input->format->es->video.frame_rate.den = hints.fpsscale;
- m_fps = hints.fpsrate / hints.fpsscale;
- }
- else
- m_fps = 0.0f;
- m_dec_input->format->flags |= MMAL_ES_FORMAT_FLAG_FRAMED;
-
- status = mmal_port_parameter_set_boolean(m_dec_input, MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, MMAL_FALSE);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to disable error concealment on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
-
- // we need an extra buffer when seeking as a picture remains on screen from old seek point
- status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_EXTRA_BUFFERS, GetAllowedReferences() + 1);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
-
- status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 1);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to disable interpolate timestamps mode on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
-
- // limit number of callback structures in video_decode to reduce latency. Too low and video hangs.
- // negative numbers have special meaning. -1=size of DPB -2=size of DPB+1
- status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS, -5);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to configure max num callbacks on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
-
- status = mmal_port_parameter_set_boolean(m_dec_input, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
-
- status = mmal_port_format_commit(m_dec_input);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to commit format for decoder input port %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
- return false;
- }
- // use a small number of large buffers to keep latency under control
- m_dec_input->buffer_size = 1024*1024;
- m_dec_input->buffer_num = 2;
-
- m_dec_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;
- status = mmal_port_enable(m_dec_input, dec_input_port_cb_static);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable decoder input port %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
- return false;
- }
-
- m_dec_output = m_dec->output[0];
-
- mmal_format_copy(m_es_format, m_dec_output->format);
-
- status = mmal_port_format_commit(m_dec_output);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to commit decoder output format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- m_dec_output->buffer_size = m_dec_output->buffer_size_min;
- m_dec_output->buffer_num = MMAL_NUM_OUTPUT_BUFFERS;
- m_dec_output->userdata = (struct MMAL_PORT_USERDATA_T *)this;
- status = mmal_port_enable(m_dec_output, dec_output_port_cb_static);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- status = mmal_component_enable(m_dec);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable decoder component %s (status=%x %s)", CLASSNAME, __func__, m_dec->name, status, mmal_status_to_string(status));
- return false;
- }
-
- m_dec_input_pool = mmal_port_pool_create(m_dec_input, m_dec_input->buffer_num, m_dec_input->buffer_size);
- if (!m_dec_input_pool)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- if (!SendCodecConfigData())
- return false;
-
- if (pool)
- pool->Prime();
- m_preroll = !m_hints.stills;
- m_speed = DVD_PLAYSPEED_NORMAL;
-
- m_processInfo.SetVideoDecoderName(m_pFormatName, true);
- m_processInfo.SetVideoDimensions(m_decoded_width, m_decoded_height);
- m_processInfo.SetVideoDAR(m_aspect_ratio);
-
- return true;
-}
-
-void CMMALVideo::Dispose()
-{
- CSingleLock lock(m_sharedSection);
- m_finished = true;
- Reset();
-}
-
-bool CMMALVideo::AddData(const DemuxPacket &packet)
-{
- uint8_t* pData = packet.pData;
- int iSize = packet.iSize;
- CSingleLock lock(m_sharedSection);
- //if (CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- // CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d dts:%.3f pts:%.3f ready_queue(%d)",
- // CLASSNAME, __func__, pData, iSize, dts == DVD_NOPTS_VALUE ? 0.0 : packet.dts*1e-6, packet.pts == DVD_NOPTS_VALUE ? 0.0 : packet.pts*1e-6, m_output_ready.size());
-
- MMAL_BUFFER_HEADER_T *buffer;
- MMAL_STATUS_T status;
- assert(pData != nullptr && iSize > 0); // no longer valid
-
- while (iSize > 0)
- {
- // 500ms timeout
- lock.Leave();
- buffer = mmal_queue_timedwait(m_dec_input_pool->queue, 500);
- if (!buffer)
- {
- CLog::Log(LOGERROR, "%s::%s - mmal_queue_get failed", CLASSNAME, __func__);
- return false;
- }
- lock.Enter();
-
- mmal_buffer_header_reset(buffer);
- buffer->cmd = 0;
- buffer->pts = packet.pts == DVD_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : packet.pts;
- buffer->dts = packet.dts == DVD_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : packet.dts;
- if (m_hints.ptsinvalid) buffer->pts = MMAL_TIME_UNKNOWN;
- buffer->length = (uint32_t)iSize > buffer->alloc_size ? buffer->alloc_size : (uint32_t)iSize;
- // set a flag so we can identify primary frames from generated frames (deinterlace)
- buffer->flags = 0;
- if (m_codecControlFlags & DVD_CODEC_CTRL_DROP_ANY)
- buffer->flags |= MMAL_BUFFER_HEADER_FLAG_USER3;
-
- if (pData)
- memcpy(buffer->data, pData, buffer->length);
- iSize -= buffer->length;
- pData += buffer->length;
-
- if (iSize == 0)
- {
- m_packet_num++;
- buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
- }
- CLog::Log(LOGDEBUG, LOGVIDEO,
- "%s::%s - %-8p %-6d/%-6d dts:%.3f pts:%.3f flags:%x ready_queue(%d)", CLASSNAME,
- __func__, static_cast<void*>(buffer), buffer->length, iSize,
- packet.dts == DVD_NOPTS_VALUE ? 0.0 : packet.dts * 1e-6,
- packet.pts == DVD_NOPTS_VALUE ? 0.0 : packet.pts * 1e-6, buffer->flags,
- m_output_ready.size());
- status = mmal_port_send_buffer(m_dec_input, buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed send buffer to decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- }
- if (packet.pts != DVD_NOPTS_VALUE)
- m_demuxerPts = packet.pts;
- else if (packet.dts != DVD_NOPTS_VALUE)
- m_demuxerPts = packet.dts;
-
- if (m_demuxerPts != DVD_NOPTS_VALUE && m_decoderPts == DVD_NOPTS_VALUE)
- m_decoderPts = m_demuxerPts;
-
- return true;
-}
-
-void CMMALVideo::Reset(void)
-{
- CSingleLock lock(m_sharedSection);
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s", CLASSNAME, __func__);
-
- if (m_dec_input && m_dec_input->is_enabled)
- mmal_port_disable(m_dec_input);
- if (m_dec_output && m_dec_output->is_enabled)
- mmal_port_disable(m_dec_output);
- if (!m_finished)
- {
- if (m_dec_input)
- mmal_port_enable(m_dec_input, dec_input_port_cb_static);
- if (m_dec_output)
- mmal_port_enable(m_dec_output, dec_output_port_cb_static);
- }
- // blow all ready video frames
- while (1)
- {
- CMMALVideoBuffer *buffer = NULL;
- {
- CSingleLock output_lock(m_output_mutex);
- // fetch a output buffer and pop it off the ready list
- if (!m_output_ready.empty())
- {
- buffer = m_output_ready.front();
- m_output_ready.pop();
- }
- m_output_cond.notifyAll();
- }
- if (buffer)
- buffer->Release();
- else
- break;
- }
-
- if (!m_finished)
- {
- SendCodecConfigData();
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- if (pool)
- pool->Prime();
- }
- m_decoderPts = DVD_NOPTS_VALUE;
- m_demuxerPts = DVD_NOPTS_VALUE;
- m_codecControlFlags = 0;
- m_num_decoded = 0;
- m_got_eos = false;
- m_packet_num = 0;
- m_packet_num_eos = ~0;
- m_preroll = !m_hints.stills && (m_speed == DVD_PLAYSPEED_NORMAL || m_speed == DVD_PLAYSPEED_PAUSE);
-}
-
-void CMMALVideo::SetSpeed(int iSpeed)
-{
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %d->%d", CLASSNAME, __func__, m_speed, iSpeed);
-
- m_speed = iSpeed;
-}
-
-CDVDVideoCodec::VCReturn CMMALVideo::GetPicture(VideoPicture* picture)
-{
- CSingleLock lock(m_sharedSection);
- MMAL_STATUS_T status;
- bool drain = (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN) ? true : false;
- bool send_eos = drain && !m_got_eos && m_packet_num_eos != m_packet_num;
-
- // we don't get an EOS response if no packets have been sent
- if (!drain)
- m_got_eos = false;
- else if (m_packet_num == 0 && send_eos)
- m_got_eos = true;
-
- if (send_eos && !m_got_eos)
- {
- MMAL_BUFFER_HEADER_T *buffer;
- // 500ms timeout
- lock.Leave();
- buffer = mmal_queue_timedwait(m_dec_input_pool->queue, 500);
- lock.Enter();
-
- if (buffer)
- {
- mmal_buffer_header_reset(buffer);
- buffer->cmd = 0;
- buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_EOS;
- m_packet_num_eos = m_packet_num;
- m_got_eos = false;
- status = mmal_port_send_buffer(m_dec_input, buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed send buffer to decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return VC_ERROR;
- }
- else
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - Send EOS (%d, %d, %d)", CLASSNAME, __func__, m_got_eos, m_packet_num, m_packet_num_eos);
- }
- else
- {
- CLog::Log(LOGWARNING, "%s::%s - mmal_queue_get failed", CLASSNAME, __func__);
- // lets assume decoder has returned all it will
- m_got_eos = true;
- }
- }
-
- // we've built up quite a lot of data in decoder - try to throttle it
- double queued = m_decoderPts != DVD_NOPTS_VALUE && m_demuxerPts != DVD_NOPTS_VALUE ? m_demuxerPts - m_decoderPts : 0.0;
- bool full = queued > DVD_MSEC_TO_TIME(1000);
- CDVDVideoCodec::VCReturn ret = CDVDVideoCodec::VC_NONE;
-
- CMMALVideoBuffer *buffer = nullptr;
- XbmcThreads::EndTime delay(500);
- while (ret == CDVDVideoCodec::VC_NONE && !delay.IsTimePast())
- {
- CSingleLock output_lock(m_output_mutex);
- unsigned int pics = m_output_ready.size();
- if (m_preroll && (pics >= GetAllowedReferences() || drain))
- m_preroll = false;
- if (pics > 0 && !m_preroll)
- {
- // fetch a output buffer and pop it off the ready list
- buffer = m_output_ready.front();
- m_output_ready.pop();
- m_output_cond.notifyAll();
- ret = CDVDVideoCodec::VC_PICTURE;
- }
- else if (m_got_eos)
- ret = CDVDVideoCodec::VC_EOF;
- else if ((m_preroll || pics <= 1) && mmal_queue_length(m_dec_input_pool->queue) > 0)
- ret = CDVDVideoCodec::VC_BUFFER;
- if (ret == CDVDVideoCodec::VC_NONE)
- {
- // otherwise we busy spin
- lock.Leave();
- m_output_cond.wait(output_lock, delay.MillisLeft());
- lock.Enter();
- }
- }
-
- if (ret == CDVDVideoCodec::VC_PICTURE)
- {
- assert(buffer && buffer->mmal_buffer);
- if (picture->videoBuffer)
- picture->videoBuffer->Release();
- picture->videoBuffer = dynamic_cast<CVideoBuffer*>(buffer);
- assert(picture->videoBuffer);
- picture->color_range = 0;
- picture->iWidth = buffer->Width() ? buffer->Width() : m_decoded_width;
- picture->iHeight = buffer->Height() ? buffer->Height() : m_decoded_height;
- picture->iDisplayWidth = picture->iWidth;
- picture->iDisplayHeight = picture->iHeight;
- //CLog::Log(LOGDEBUG, "%s::%s - %dx%d %dx%d %dx%d %dx%d %f,%f", CLASSNAME, __func__, picture->iWidth, picture->iHeight, picture->iDisplayWidth, picture->iDisplayHeight, m_decoded_width, m_decoded_height, buffer->Width(), buffer->Height(), buffer->m_aspect_ratio, m_hints.aspect);
-
- if (buffer->m_aspect_ratio > 0.0)
- {
- picture->iDisplayWidth = ((int)lrint(picture->iHeight * buffer->m_aspect_ratio)) & -3;
- if (picture->iDisplayWidth > picture->iWidth)
- {
- picture->iDisplayWidth = picture->iWidth;
- picture->iDisplayHeight = ((int)lrint(picture->iWidth / buffer->m_aspect_ratio)) & -3;
- }
- }
-
- // timestamp is in microseconds
- picture->dts = buffer->mmal_buffer->dts == MMAL_TIME_UNKNOWN ? DVD_NOPTS_VALUE : buffer->mmal_buffer->dts;
- picture->pts = buffer->mmal_buffer->pts == MMAL_TIME_UNKNOWN ? DVD_NOPTS_VALUE : buffer->mmal_buffer->pts;
- picture->iRepeatPicture = 0;
- picture->iFlags = 0;
- if (buffer->mmal_buffer->flags & MMAL_BUFFER_HEADER_FLAG_USER3)
- picture->iFlags |= DVP_FLAG_DROPPED;
- CLog::Log(LOGINFO, LOGVIDEO,
- "%s::%s dts:%.3f pts:%.3f flags:%x:%x MMALBuffer:%p mmal_buffer:%p", CLASSNAME,
- __func__, picture->dts == DVD_NOPTS_VALUE ? 0.0 : picture->dts * 1e-6,
- picture->pts == DVD_NOPTS_VALUE ? 0.0 : picture->pts * 1e-6, picture->iFlags,
- buffer->mmal_buffer->flags, static_cast<void*>(buffer),
- static_cast<void*>(buffer->mmal_buffer));
- assert(!(buffer->mmal_buffer->flags & MMAL_BUFFER_HEADER_FLAG_DECODEONLY));
- buffer->mmal_buffer->flags &= ~MMAL_BUFFER_HEADER_FLAG_USER3;
- buffer->m_stills = m_hints.stills;
- }
-
- if (ret == CDVDVideoCodec::VC_NONE)
- CLog::Log(LOGWARNING, "%s::%s - ret(%x) pics(%d) inputs(%d) slept(%2d) queued(%.2f) (%.2f:%.2f) full(%d) flags(%x) preroll(%d) eos(%d %d/%d)", CLASSNAME, __func__, ret, m_output_ready.size(), mmal_queue_length(m_dec_input_pool->queue), 500-delay.MillisLeft(), queued*1e-6, m_demuxerPts*1e-6, m_decoderPts*1e-6, full, m_codecControlFlags, m_preroll, m_got_eos, m_packet_num, m_packet_num_eos);
- else
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - ret(%x) pics(%d) inputs(%d) slept(%2d) queued(%.2f) (%.2f:%.2f) full(%d) flags(%x) preroll(%d) eos(%d %d/%d)", CLASSNAME, __func__, ret, m_output_ready.size(), mmal_queue_length(m_dec_input_pool->queue), 500-delay.MillisLeft(), queued*1e-6, m_demuxerPts*1e-6, m_decoderPts*1e-6, full, m_codecControlFlags, m_preroll, m_got_eos, m_packet_num, m_packet_num_eos);
-
- return ret;
-}
-
-void CMMALVideo::SetCodecControl(int flags)
-{
- CSingleLock lock(m_sharedSection);
- if (m_codecControlFlags != flags)
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %x->%x", CLASSNAME, __func__, m_codecControlFlags, flags);
- m_codecControlFlags = flags;
-}
-
-CDVDVideoCodec* CMMALVideo::Create(CProcessInfo &processInfo)
- {
- return new CMMALVideo(processInfo);
- }
-
-void CMMALVideo::Register()
-{
- CDVDFactoryCodec::RegisterHWVideoCodec("mmal", CMMALVideo::Create);
-}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h
deleted file mode 100644
index 0e5e27ce39..0000000000
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2010-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 "DVDVideoCodec.h"
-#include "cores/VideoPlayer/DVDResource.h"
-#include "cores/VideoPlayer/DVDStreamInfo.h"
-#include "cores/VideoPlayer/VideoRenderers/BaseRenderer.h"
-#include "cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h"
-#include "cores/VideoSettings.h"
-#include "rendering/RenderSystem.h"
-#include "threads/Event.h"
-#include "utils/Geometry.h"
-
-#include <memory>
-#include <queue>
-#include <string>
-
-#include <semaphore.h>
-
-namespace MMAL {
-
-class CMMALVideo;
-class CMMALPool;
-
-// a mmal video frame
-class CMMALVideoBuffer : public CMMALBuffer
-{
-public:
- CMMALVideoBuffer(int id);
- virtual ~CMMALVideoBuffer();
-protected:
-};
-
-class CMMALVideo : public CDVDVideoCodec
-{
-public:
- CMMALVideo(CProcessInfo &processInfo);
- virtual ~CMMALVideo();
-
- // Required overrides
- virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) override;
- virtual bool AddData(const DemuxPacket &packet) override;
- virtual void Reset(void) override;
- virtual CDVDVideoCodec::VCReturn GetPicture(VideoPicture *pDvdVideoPicture) override;
- virtual unsigned GetAllowedReferences() override { return 4; }
- virtual const char* GetName(void) override { return m_pFormatName ? m_pFormatName:"mmal-xxx"; }
- virtual void SetCodecControl(int flags) override;
- virtual void SetSpeed(int iSpeed) override;
-
- // MMAL decoder callback routines.
- void dec_output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
- void dec_control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
- void dec_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
- static CDVDVideoCodec* Create(CProcessInfo &processInfo);
- static void Register();
-
-protected:
- void QueryCodec(void);
- void Dispose(void);
-
- // Video format
- unsigned int m_decoded_width;
- unsigned int m_decoded_height;
- unsigned int m_decoded_aligned_width;
- unsigned int m_decoded_aligned_height;
- unsigned int m_egl_buffer_count;
- bool m_finished;
- float m_aspect_ratio;
- const char *m_pFormatName;
-
- // mmal output buffers (video frames)
- CCriticalSection m_output_mutex;
- XbmcThreads::ConditionVariable m_output_cond;
- std::queue<CMMALVideoBuffer*> m_output_ready;
-
- // initialize mmal and get decoder component
- bool Initialize( const std::string &decoder_name);
- void PortSettingsChanged(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
- bool SendCodecConfigData();
-
- CDVDStreamInfo m_hints;
- float m_fps;
- unsigned m_num_decoded;
- // Components
- MMAL_INTERLACETYPE_T m_interlace_mode;
- double m_demuxerPts;
- double m_decoderPts;
- int m_speed;
- int m_codecControlFlags;
- bool m_preroll;
- bool m_got_eos;
- uint32_t m_packet_num;
- uint32_t m_packet_num_eos;
-
- CCriticalSection m_sharedSection;
- MMAL_COMPONENT_T *m_dec;
- MMAL_PORT_T *m_dec_input;
- MMAL_PORT_T *m_dec_output;
- MMAL_POOL_T *m_dec_input_pool;
- std::shared_ptr<CMMALPool> m_pool;
-
- MMAL_ES_FORMAT_T *m_es_format;
-
- MMAL_FOURCC_T m_codingType;
- VideoPicture* m_lastDvdVideoPicture;
-
- bool change_dec_output_format();
-};
-
-};
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp
deleted file mode 100644
index 28eff23f16..0000000000
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * 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.
- */
-
-#include <interface/mmal/util/mmal_default_components.h>
-
-#include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
-#include "../DVDCodecUtils.h"
-#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
-#include "MMALFFmpeg.h"
-#include "utils/log.h"
-#include "utils/StringUtils.h"
-#include "platform/linux/RBP.h"
-#include "settings/AdvancedSettings.h"
-
-extern "C" {
-#include <libavutil/imgutils.h>
-}
-
-using namespace MMAL;
-
-//-----------------------------------------------------------------------------
-// MMAL Buffers
-//-----------------------------------------------------------------------------
-
-#define CLASSNAME "CMMALYUVBuffer"
-
-#define VERBOSE 0
-
-CMMALYUVBuffer::CMMALYUVBuffer(int id)
- : CMMALBuffer(id)
-{
-}
-
-CMMALYUVBuffer::~CMMALYUVBuffer()
-{
- delete m_gmem;
-}
-
-uint8_t* CMMALYUVBuffer::GetMemPtr()
-{
- if (!m_gmem)
- return nullptr;
- return static_cast<uint8_t *>(m_gmem->m_arm);
-}
-
-void CMMALYUVBuffer::GetPlanes(uint8_t*(&planes)[YuvImage::MAX_PLANES])
-{
- for (int i = 0; i < YuvImage::MAX_PLANES; i++)
- planes[i] = nullptr;
-
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- assert(pool);
- AVRpiZcFrameGeometry geo = pool->GetGeometry();
-
- if (VERBOSE)
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d %dx%d (%dx%d %dx%d)", CLASSNAME, __FUNCTION__, geo.getStrideY(), geo.getHeightY(), geo.getStrideC(), geo.getHeightC(), Width(), Height(), AlignedWidth(), AlignedHeight());
-
- planes[0] = GetMemPtr();
- if (planes[0] && geo.getPlanesC() >= 1)
- planes[1] = planes[0] + geo.getSizeY();
- if (planes[1] && geo.getPlanesC() >= 2)
- planes[2] = planes[1] + geo.getSizeC();
-}
-
-void CMMALYUVBuffer::GetStrides(int(&strides)[YuvImage::MAX_PLANES])
-{
- for (int i = 0; i < YuvImage::MAX_PLANES; i++)
- strides[i] = 0;
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- assert(pool);
- AVRpiZcFrameGeometry geo = pool->GetGeometry();
- strides[0] = geo.getStrideY();
- strides[1] = geo.getStrideC();
- strides[2] = geo.getStrideC();
-}
-
-void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES])
-{
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- assert(pool);
- pool->SetDimensions(width, height, strides, planeOffsets);
-}
-
-void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES])
-{
- const int (&planeOffsets)[YuvImage::MAX_PLANES] = {};
- SetDimensions(width, height, strides, planeOffsets);
-}
-
-CGPUMEM *CMMALYUVBuffer::Allocate(int size, void *opaque)
-{
- m_gmem = new CGPUMEM(size, true);
- if (m_gmem && m_gmem->m_vc)
- {
- m_gmem->m_opaque = opaque;
- }
- else
- {
- delete m_gmem;
- m_gmem = nullptr;
- }
- return m_gmem;
-}
-
-
-//-----------------------------------------------------------------------------
-// MMAL Decoder
-//-----------------------------------------------------------------------------
-
-#undef CLASSNAME
-#define CLASSNAME "CDecoder"
-
-void CDecoder::AlignedSize(AVCodecContext *avctx, int &width, int &height)
-{
- if (!avctx)
- return;
- int w = width, h = height;
- AVFrame picture;
- int unaligned;
- int stride_align[AV_NUM_DATA_POINTERS];
-
- avcodec_align_dimensions2(avctx, &w, &h, stride_align);
-
- do {
- // NOTE: do not align linesizes individually, this breaks e.g. assumptions
- // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2
- av_image_fill_linesizes(picture.linesize, avctx->pix_fmt, w);
- // increase alignment of w for next try (rhs gives the lowest bit set in w)
- w += w & ~(w - 1);
-
- unaligned = 0;
- for (int i = 0; i < 4; i++)
- unaligned |= picture.linesize[i] % stride_align[i];
- } while (unaligned);
- width = w;
- height = h;
-}
-
-CDecoder::CDecoder(CProcessInfo &processInfo, CDVDStreamInfo &hints) : m_processInfo(processInfo), m_hints(hints)
-{
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - create %p", CLASSNAME, __FUNCTION__, static_cast<void*>(this));
- m_avctx = nullptr;
- m_pool = nullptr;
-}
-
-CDecoder::~CDecoder()
-{
- if (m_renderBuffer)
- m_renderBuffer->Release();
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - destroy %p", CLASSNAME, __FUNCTION__, static_cast<void*>(this));
-}
-
-long CDecoder::Release()
-{
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - m_refs:%ld", CLASSNAME, __FUNCTION__, m_refs.load());
- return IHardwareDecoder::Release();
-}
-
-void CDecoder::FFReleaseBuffer(void *opaque, uint8_t *data)
-{
- CGPUMEM *gmem = (CGPUMEM *)opaque;
- CMMALYUVBuffer *YUVBuffer = (CMMALYUVBuffer *)gmem->m_opaque;
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s buf:%p gmem:%p", CLASSNAME, __FUNCTION__,
- static_cast<void*>(YUVBuffer), static_cast<void*>(gmem));
-
- YUVBuffer->Release();
-}
-
-int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *frame, int flags)
-{
- ICallbackHWAccel* cb = static_cast<ICallbackHWAccel*>(avctx->opaque);
- CDecoder* dec = static_cast<CDecoder*>(cb->GetHWAccel());
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d format:%x:%x flags:%x", CLASSNAME, __FUNCTION__, frame->width, frame->height, frame->format, dec->m_fmt, flags);
-
- if ((avctx->codec && (avctx->codec->capabilities & AV_CODEC_CAP_DR1) == 0) || frame->format != dec->m_fmt)
- {
- assert(0);
- return avcodec_default_get_buffer2(avctx, frame, flags);
- }
-
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(dec->m_pool);
- if (!pool->IsConfigured())
- {
- int aligned_width = frame->width;
- int aligned_height = frame->height;
- if (pool->Encoding() != MMAL_ENCODING_YUVUV128 && pool->Encoding() != MMAL_ENCODING_YUVUV64_16)
- {
- // ffmpeg requirements
- AlignedSize(dec->m_avctx, aligned_width, aligned_height);
- // GPU requirements
- aligned_width = ALIGN_UP(aligned_width, 32);
- aligned_height = ALIGN_UP(aligned_height, 16);
- }
- pool->Configure(dec->m_fmt, frame->width, frame->height, aligned_width, aligned_height, 0);
- }
- CMMALYUVBuffer *YUVBuffer = dynamic_cast<CMMALYUVBuffer *>(pool->Get());
- if (!YUVBuffer)
- {
- CLog::Log(LOGERROR,"%s::%s Failed to allocated buffer in time", CLASSNAME, __FUNCTION__);
- return -1;
- }
- assert(YUVBuffer->mmal_buffer);
-
- CGPUMEM *gmem = YUVBuffer->GetMem();
- assert(gmem);
-
- AVBufferRef *buf = av_buffer_create((uint8_t *)gmem->m_arm, gmem->m_numbytes, CDecoder::FFReleaseBuffer, gmem, AV_BUFFER_FLAG_READONLY);
- if (!buf)
- {
- CLog::Log(LOGERROR, "%s::%s av_buffer_create() failed", CLASSNAME, __FUNCTION__);
- YUVBuffer->Release();
- return -1;
- }
-
- uint8_t *planes[YuvImage::MAX_PLANES];
- int strides[YuvImage::MAX_PLANES];
- YUVBuffer->GetPlanes(planes);
- YUVBuffer->GetStrides(strides);
-
- for (int i = 0; i < AV_NUM_DATA_POINTERS; i++)
- {
- frame->data[i] = i < YuvImage::MAX_PLANES ? planes[i] : nullptr;
- frame->linesize[i] = i < YuvImage::MAX_PLANES ? strides[i] : 0;
- frame->buf[i] = i == 0 ? buf : nullptr;
- }
-
- frame->extended_data = frame->data;
- // Leave extended buf alone
-
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s buf:%p mmal:%p gmem:%p avbuf:%p:%p:%p", CLASSNAME,
- __FUNCTION__, static_cast<void*>(YUVBuffer), static_cast<void*>(YUVBuffer->mmal_buffer),
- static_cast<void*>(gmem), static_cast<void*>(frame->data[0]),
- static_cast<void*>(frame->data[1]), static_cast<void*>(frame->data[2]));
-
- return 0;
-}
-
-
-bool CDecoder::Open(AVCodecContext *avctx, AVCodecContext* mainctx, enum AVPixelFormat fmt)
-{
- CSingleLock lock(m_section);
-
- CLog::Log(LOGINFO, "%s::%s - fmt:%d", CLASSNAME, __FUNCTION__, fmt);
-
- CLog::Log(LOGDEBUG, "%s::%s MMAL - source requires %d references", CLASSNAME, __FUNCTION__, avctx->refs);
-
- avctx->get_buffer2 = CDecoder::FFGetBuffer;
- mainctx->get_buffer2 = CDecoder::FFGetBuffer;
-
- m_avctx = mainctx;
- m_fmt = fmt;
-
- /* Create dummy component with attached pool */
- m_pool = std::make_shared<CMMALPool>(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, false, MMAL_NUM_OUTPUT_BUFFERS, 0, MMAL_ENCODING_UNKNOWN, MMALStateFFDec);
- if (!m_pool)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder output", CLASSNAME, __func__);
- return false;
- }
-
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- pool->SetProcessInfo(&m_processInfo);
-
- std::list<EINTERLACEMETHOD> deintMethods;
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_AUTO);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_ADVANCED);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_BOB);
- deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_MMAL_BOB_HALF);
- m_processInfo.UpdateDeinterlacingMethods(deintMethods);
-
- return true;
-}
-
-CDVDVideoCodec::VCReturn CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
-{
- CSingleLock lock(m_section);
-
- if (frame)
- {
- if ((frame->format != AV_PIX_FMT_YUV420P && frame->format != AV_PIX_FMT_YUV420P10 && frame->format != AV_PIX_FMT_YUV420P12 && frame->format != AV_PIX_FMT_YUV420P14 && frame->format != AV_PIX_FMT_YUV420P16 &&
- frame->format != AV_PIX_FMT_BGR0 && frame->format != AV_PIX_FMT_RGB565LE) ||
- frame->buf[1] != nullptr || frame->buf[0] == nullptr)
- {
- CLog::Log(LOGERROR, "%s::%s frame format invalid format:%d buf:%p,%p", CLASSNAME, __func__,
- frame->format, static_cast<void*>(frame->buf[0]),
- static_cast<void*>(frame->buf[1]));
- return CDVDVideoCodec::VC_ERROR;
- }
- CVideoBuffer *old = m_renderBuffer;
- if (m_renderBuffer)
- m_renderBuffer->Release();
-
- CGPUMEM *m_gmem = (CGPUMEM *)av_buffer_get_opaque(frame->buf[0]);
- assert(m_gmem);
- // need to flush ARM cache so GPU can see it
- m_gmem->Flush();
- m_renderBuffer = static_cast<CMMALYUVBuffer*>(m_gmem->m_opaque);
- assert(m_renderBuffer && m_renderBuffer->mmal_buffer);
- if (m_renderBuffer)
- {
- m_renderBuffer->m_stills = m_hints.stills;
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - mmal:%p buf:%p old:%p gpu:%p %dx%d (%dx%d)",
- CLASSNAME, __FUNCTION__, static_cast<void*>(m_renderBuffer->mmal_buffer),
- static_cast<void*>(m_renderBuffer), static_cast<void*>(old),
- static_cast<void*>(m_renderBuffer->GetMem()), m_renderBuffer->Width(),
- m_renderBuffer->Height(), m_renderBuffer->AlignedWidth(),
- m_renderBuffer->AlignedHeight());
- m_renderBuffer->Acquire();
- }
- }
-
- CDVDVideoCodec::VCReturn status = Check(avctx);
- if (status != CDVDVideoCodec::VC_NONE)
- return status;
-
- if (frame)
- return CDVDVideoCodec::VC_PICTURE;
- else
- return CDVDVideoCodec::VC_BUFFER;
-}
-
-bool CDecoder::GetPicture(AVCodecContext* avctx, VideoPicture* picture)
-{
- CSingleLock lock(m_section);
-
- bool ret = ((ICallbackHWAccel*)avctx->opaque)->GetPictureCommon(picture);
- if (!ret || !m_renderBuffer)
- return false;
-
- CVideoBuffer *old = picture->videoBuffer;
- if (picture->videoBuffer)
- picture->videoBuffer->Release();
-
- picture->videoBuffer = m_renderBuffer;
- CLog::Log(
- LOGDEBUG, LOGVIDEO, "%s::%s - mmal:%p dts:%.3f pts:%.3f buf:%p old:%p gpu:%p %dx%d (%dx%d)",
- CLASSNAME, __FUNCTION__, static_cast<void*>(m_renderBuffer->mmal_buffer), 1e-6 * picture->dts,
- 1e-6 * picture->pts, static_cast<void*>(m_renderBuffer), static_cast<void*>(old),
- static_cast<void*>(m_renderBuffer->GetMem()), m_renderBuffer->Width(),
- m_renderBuffer->Height(), m_renderBuffer->AlignedWidth(), m_renderBuffer->AlignedHeight());
- picture->videoBuffer->Acquire();
-
- return true;
-}
-
-CDVDVideoCodec::VCReturn CDecoder::Check(AVCodecContext* avctx)
-{
- CSingleLock lock(m_section);
- return CDVDVideoCodec::VC_NONE;
-}
-
-unsigned CDecoder::GetAllowedReferences()
-{
- return 6;
-}
-
-IHardwareDecoder* CDecoder::Create(CDVDStreamInfo &hint, CProcessInfo &processInfo, AVPixelFormat fmt)
- {
- return new CDecoder(processInfo, hint);
- }
-
-void CDecoder::Register()
-{
- CDVDFactoryCodec::RegisterHWAccel("mmalffmpeg", CDecoder::Create);
-}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h
deleted file mode 100644
index 74106a770b..0000000000
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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
-
-#include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h"
-#include "cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h"
-
-#include <memory>
-#include <queue>
-
-#include <libavcodec/avcodec.h>
-
-struct MMAL_BUFFER_HEADER_T;
-class CGPUMEM;
-
-namespace MMAL {
-
-class CDecoder;
-
-// a mmal video frame
-class CMMALYUVBuffer : public CMMALBuffer
-{
-public:
- CMMALYUVBuffer(int id);
- virtual ~CMMALYUVBuffer();
- uint8_t* GetMemPtr() override;
- virtual void GetPlanes(uint8_t*(&planes)[YuvImage::MAX_PLANES]) override;
- virtual void GetStrides(int(&strides)[YuvImage::MAX_PLANES]) override;
- virtual void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]) override;
- virtual void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) override;
- CGPUMEM *Allocate(int size, void *opaque);
- CGPUMEM *GetMem() { return m_gmem; }
-protected:
- CGPUMEM *m_gmem = nullptr;
-};
-
-class CDecoder
- : public IHardwareDecoder
-{
-public:
- CDecoder(CProcessInfo& processInfo, CDVDStreamInfo &hints);
- virtual ~CDecoder();
- virtual bool Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum AVPixelFormat) override;
- virtual CDVDVideoCodec::VCReturn Decode(AVCodecContext* avctx, AVFrame* frame) override;
- virtual bool GetPicture(AVCodecContext* avctx, VideoPicture* picture) override;
- virtual CDVDVideoCodec::VCReturn Check(AVCodecContext* avctx) override;
- virtual const std::string Name() override { return "mmal"; }
- virtual unsigned GetAllowedReferences() override;
- virtual long Release() override;
-
- static void AlignedSize(AVCodecContext *avctx, int &width, int &height);
- static void FFReleaseBuffer(void *opaque, uint8_t *data);
- static int FFGetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags);
- static IHardwareDecoder* Create(CDVDStreamInfo &hint, CProcessInfo &processInfo, AVPixelFormat fmt);
- static void Register();
-
-protected:
- AVCodecContext *m_avctx;
- CProcessInfo &m_processInfo;
- CCriticalSection m_section;
- std::shared_ptr<CMMALPool> m_pool;
- enum AVPixelFormat m_fmt;
- CDVDStreamInfo m_hints;
- CMMALYUVBuffer *m_renderBuffer = nullptr;
-};
-
-};
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
index 9fc1efea5a..7f243c3159 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
@@ -2202,7 +2202,7 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamAudioState()
if (!m_startTime)
{
m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001;
- m_seekStream = i;
+ m_seekStream = idx;
}
return TRANSPORT_STREAM_STATE::READY;
}
@@ -2255,7 +2255,7 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamVideoState()
if (!m_startTime)
{
m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001;
- m_seekStream = i;
+ m_seekStream = idx;
}
return TRANSPORT_STREAM_STATE::READY;
}
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
index 93ec1639a0..314214bb44 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
@@ -865,7 +865,7 @@ void CDVDInputStreamBluray::OverlayCallbackARGB(const struct bd_argb_overlay_s *
/* uncompress and draw bitmap */
if (ov->argb && ov->cmd == BD_ARGB_OVERLAY_DRAW)
{
- SOverlay overlay(new CDVDOverlayImage(), std::ptr_fun(CDVDOverlay::Release));
+ SOverlay overlay(new CDVDOverlayImage(), [](CDVDOverlay* ov) { CDVDOverlay::Release(ov); });
overlay->palette_colors = 0;
overlay->palette = nullptr;
diff --git a/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt b/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt
deleted file mode 100644
index 1a41576405..0000000000
--- a/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- set(SOURCES ProcessInfoPi.cpp)
-
- set(HEADERS ProcessInfoPi.h)
-
- core_add_library(processPi)
-endif()
diff --git a/xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.cpp b/xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.cpp
deleted file mode 100644
index 79ab42758c..0000000000
--- a/xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2005-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "ProcessInfoPi.h"
-
-#include "cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h"
-
-#include "platform/linux/RBP.h"
-
-#include <interface/mmal/util/mmal_default_components.h>
-
-// Override for platform ports
-using namespace MMAL;
-
-CProcessInfo* CProcessInfoPi::Create()
-{
- return new CProcessInfoPi();
-}
-
-CProcessInfoPi::CProcessInfoPi()
-{
- /* Create dummy component with attached pool */
- std::shared_ptr<IVideoBufferPool> pool = std::make_shared<CMMALPool>(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, false, MMAL_NUM_OUTPUT_BUFFERS, 0, MMAL_ENCODING_UNKNOWN, MMALStateFFDec);
- m_videoBufferManager.RegisterPool(pool);
-}
-
-void CProcessInfoPi::Register()
-{
- CProcessInfo::RegisterProcessControl("rbpi", CProcessInfoPi::Create);
-}
-
-EINTERLACEMETHOD CProcessInfoPi::GetFallbackDeintMethod()
-{
- return EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE_HALF;
-}
-
-bool CProcessInfoPi::AllowDTSHDDecode()
-{
- if (g_RBP.RaspberryPiVersion() == 1)
- return false;
- return true;
-}
diff --git a/xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.h b/xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.h
deleted file mode 100644
index 24334a43b0..0000000000
--- a/xbmc/cores/VideoPlayer/Process/rbpi/ProcessInfoPi.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 "cores/IPlayer.h"
-#include "cores/VideoPlayer/Process/ProcessInfo.h"
-
-namespace MMAL {
- class CMMALYUVBuffer;
-}
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-class CVideoBufferManagerPi : public CVideoBufferManager
-{
-public:
- CVideoBufferManagerPi();
- void RegisterPool(std::shared_ptr<IVideoBufferPool> pool);
- void ReleasePools();
- CVideoBuffer* Get(AVPixelFormat format, int width, int height);
- CVideoBuffer* Get(AVPixelFormat format, int size);
- void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]);
-
-protected:
-};
-
-class CProcessInfoPi : public CProcessInfo
-{
-public:
- CProcessInfoPi();
- static CProcessInfo* Create();
- static void Register();
- EINTERLACEMETHOD GetFallbackDeintMethod() override;
- bool AllowDTSHDDecode() override;
-
-//protected:
-};
diff --git a/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.cpp b/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.cpp
index 04aaec66d4..847ba6e95f 100644
--- a/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.cpp
+++ b/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.cpp
@@ -8,6 +8,7 @@
#include "ProcessInfoWayland.h"
+#include "cores/VideoPlayer/Buffers/VideoBufferPoolDMA.h"
#include "threads/SingleLock.h"
using namespace VIDEOPLAYER;
@@ -22,6 +23,11 @@ void CProcessInfoWayland::Register()
CProcessInfo::RegisterProcessControl("Wayland", CProcessInfoWayland::Create);
}
+CProcessInfoWayland::CProcessInfoWayland()
+{
+ m_videoBufferManager.RegisterPool(std::make_shared<CVideoBufferPoolDMA>());
+}
+
void CProcessInfoWayland::SetSwDeinterlacingMethods()
{
// first populate with the defaults from base implementation
diff --git a/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.h b/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.h
index 00c5a35abc..91df3f7335 100644
--- a/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.h
+++ b/xbmc/cores/VideoPlayer/Process/wayland/ProcessInfoWayland.h
@@ -19,6 +19,7 @@ public:
static CProcessInfo* Create();
static void Register();
+ CProcessInfoWayland();
void SetSwDeinterlacingMethods() override;
std::vector<AVPixelFormat> GetRenderFormats() override;
};
diff --git a/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp b/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
index 74aea898c1..f93ca6c2cc 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
@@ -19,9 +19,6 @@
#include "utils/MathUtils.h"
#include "cores/AudioEngine/Interfaces/AE.h"
#include "cores/AudioEngine/Utils/AEUtil.h"
-#ifdef TARGET_RASPBERRY_PI
-#include "platform/linux/RBP.h"
-#endif
#include <sstream>
#include <iomanip>
diff --git a/xbmc/cores/VideoPlayer/VideoPlayerRadioRDS.cpp b/xbmc/cores/VideoPlayer/VideoPlayerRadioRDS.cpp
index 6d026ba629..7eac1c7fd4 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayerRadioRDS.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayerRadioRDS.cpp
@@ -522,22 +522,21 @@ bool CDVDRadioRDSData::CheckStream(CDVDStreamInfo &hints)
bool CDVDRadioRDSData::OpenStream(CDVDStreamInfo hints)
{
+ CloseStream(true);
+
m_messageQueue.Init();
if (hints.type == STREAM_RADIO_RDS)
{
Flush();
CLog::Log(LOGINFO, "Creating UECP (RDS) data thread");
Create();
+ return true;
}
- return true;
+ return false;
}
void CDVDRadioRDSData::CloseStream(bool bWaitForBuffers)
{
- // wait until buffers are empty
- if (bWaitForBuffers)
- m_messageQueue.WaitUntilEmpty();
-
m_messageQueue.Abort();
// wait for decode_video thread to end
@@ -547,7 +546,8 @@ void CDVDRadioRDSData::CloseStream(bool bWaitForBuffers)
m_messageQueue.End();
m_currentInfoTag.reset();
- m_currentChannel->SetRadioRDSInfoTag(m_currentInfoTag);
+ if (m_currentChannel)
+ m_currentChannel->SetRadioRDSInfoTag(m_currentInfoTag);
m_currentChannel.reset();
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp
index 3b1e03de02..d33a1c65fe 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp
@@ -9,7 +9,6 @@
#include "ColorManager.h"
#include "ServiceBroker.h"
-#include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
#include "filesystem/File.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -85,21 +84,25 @@ bool CColorManager::IsValid() const
}
}
-CMS_PRIMARIES videoFlagsToPrimaries(int flags)
+CMS_PRIMARIES avColorToCmsPrimaries(AVColorPrimaries primaries)
{
- if (flags & CONF_FLAGS_COLPRI_BT709)
- return CMS_PRIMARIES_BT709;
- if (flags & CONF_FLAGS_COLPRI_BT2020)
- return CMS_PRIMARIES_BT2020;
- if (flags & CONF_FLAGS_COLPRI_170M)
- return CMS_PRIMARIES_170M;
- if (flags & CONF_FLAGS_COLPRI_BT470M)
- return CMS_PRIMARIES_BT470M;
- if (flags & CONF_FLAGS_COLPRI_BT470BG)
- return CMS_PRIMARIES_BT470BG;
- if (flags & CONF_FLAGS_COLPRI_240M)
- return CMS_PRIMARIES_240M;
- return CMS_PRIMARIES_BT709; // default to bt.709
+ switch (primaries)
+ {
+ case AVCOL_PRI_BT709:
+ return CMS_PRIMARIES_BT709;
+ case AVCOL_PRI_BT470M:
+ return CMS_PRIMARIES_BT470M;
+ case AVCOL_PRI_BT470BG:
+ return CMS_PRIMARIES_BT470BG;
+ case AVCOL_PRI_SMPTE170M:
+ return CMS_PRIMARIES_170M;
+ case AVCOL_PRI_SMPTE240M:
+ return CMS_PRIMARIES_240M;
+ case AVCOL_PRI_BT2020:
+ return CMS_PRIMARIES_BT2020;
+ default:
+ return CMS_PRIMARIES_BT709;
+ }
}
bool CColorManager::Get3dLutSize(CMS_DATA_FORMAT format, int *clutSize, int *dataSize)
@@ -152,10 +155,11 @@ bool CColorManager::Get3dLutSize(CMS_DATA_FORMAT format, int *clutSize, int *dat
}
}
-bool CColorManager::GetVideo3dLut(int videoFlags, int *cmsToken, CMS_DATA_FORMAT format, int clutSize, uint16_t *clutData)
+bool CColorManager::GetVideo3dLut(AVColorPrimaries srcPrimaries, int* cmsToken,
+ CMS_DATA_FORMAT format, int clutSize, uint16_t* clutData)
{
const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
- CMS_PRIMARIES videoPrimaries = videoFlagsToPrimaries(videoFlags);
+ CMS_PRIMARIES videoPrimaries = avColorToCmsPrimaries(srcPrimaries);
CLog::Log(LOGDEBUG, "ColorManager: video primaries: %d", (int)videoPrimaries);
switch (settings->GetInt("videoscreen.cmsmode"))
{
@@ -240,7 +244,7 @@ bool CColorManager::GetVideo3dLut(int videoFlags, int *cmsToken, CMS_DATA_FORMAT
return true;
}
-bool CColorManager::CheckConfiguration(int cmsToken, int flags)
+bool CColorManager::CheckConfiguration(int cmsToken, AVColorPrimaries srcPrimaries)
{
if (cmsToken != m_curCmsToken)
return false;
@@ -261,7 +265,8 @@ bool CColorManager::CheckConfiguration(int cmsToken, int flags)
return false; // whitepoint changed
{
CMS_PRIMARIES primaries = static_cast<CMS_PRIMARIES>(settings->GetInt("videoscreen.cmsprimaries"));
- if (primaries == CMS_PRIMARIES_AUTO) primaries = videoFlagsToPrimaries(flags);
+ if (primaries == CMS_PRIMARIES_AUTO)
+ primaries = avColorToCmsPrimaries(srcPrimaries);
if (m_curIccPrimaries != primaries)
return false; // primaries changed
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h
index 7da789c825..a6c50ea3bb 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h
@@ -14,6 +14,11 @@
#include <string>
+extern "C"
+{
+#include <libavutil/pixfmt.h>
+}
+
enum CMS_DATA_FORMAT
{
CMS_DATA_FMT_RGB,
@@ -76,22 +81,23 @@ public:
/*!
\brief Get a 3D LUT for video color correction
- \param primaries video primaries (see CONF_FLAGS_COLPRI)
+ \param srcPrimaries video primaries (see AVColorPrimaries)
\param cmsToken pointer to a color manager configuration token
\param format of CLUT data
\param clutSize CLUT resolution
\param clutData pointer to CLUT data
\return true on success, false otherwise
*/
- bool GetVideo3dLut(int primaries, int *cmsToken, CMS_DATA_FORMAT format, int clutSize, uint16_t *clutData);
+ bool GetVideo3dLut(AVColorPrimaries srcPrimaries, int* cmsToken, CMS_DATA_FORMAT format,
+ int clutSize, uint16_t* clutData);
/*!
\brief Check if a 3D LUT is still valid
\param cmsToken pointer to a color manager configuration token
- \param flags video renderer flags (see CONF_FLAGS_COLPRI)
+ \param srcPrimaries video primaries (see AVColorPrimaries)
\return true on valid, false if 3D LUT should be reloaded
*/
- bool CheckConfiguration(int cmsToken, int flags);
+ bool CheckConfiguration(int cmsToken, AVColorPrimaries srcPrimaries);
/*!
\brief Get a 3D LUT dimention and data size for video color correction
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/CMakeLists.txt
index 6184affccf..742c7e4514 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/CMakeLists.txt
@@ -32,11 +32,6 @@ if(CORE_SYSTEM_NAME STREQUAL darwin_embedded)
list(APPEND HEADERS RendererVTBGLES.h)
endif()
-if(MMAL_FOUND)
- list(APPEND SOURCES MMALRenderer.cpp)
- list(APPEND HEADERS MMALRenderer.h)
-endif()
-
if(CORE_SYSTEM_NAME STREQUAL android)
list(APPEND SOURCES RendererMediaCodec.cpp
RendererMediaCodecSurface.cpp)
@@ -44,11 +39,14 @@ if(CORE_SYSTEM_NAME STREQUAL android)
RendererMediaCodecSurface.h)
endif()
-if(CORE_PLATFORM_NAME_LC STREQUAL gbm)
- list(APPEND SOURCES RendererDRMPRIME.cpp
- VideoLayerBridgeDRMPRIME.cpp)
- list(APPEND HEADERS RendererDRMPRIME.h
- VideoLayerBridgeDRMPRIME.h)
+if(CORE_PLATFORM_NAME_LC STREQUAL gbm OR CORE_PLATFORM_NAME_LC STREQUAL wayland)
+ if(CORE_PLATFORM_NAME_LC STREQUAL gbm)
+ list(APPEND SOURCES RendererDRMPRIME.cpp
+ VideoLayerBridgeDRMPRIME.cpp)
+ list(APPEND HEADERS RendererDRMPRIME.h
+ VideoLayerBridgeDRMPRIME.h)
+ endif()
+
if(OPENGLES_FOUND)
list(APPEND SOURCES RendererDRMPRIMEGLES.cpp
DRMPRIMEEGL.cpp)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp
deleted file mode 100644
index 0c73642887..0000000000
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp
+++ /dev/null
@@ -1,1570 +0,0 @@
-/*
- * Copyright (C) 2005-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include <interface/mmal/util/mmal_util.h>
-#include <interface/mmal/util/mmal_default_components.h>
-#include <interface/mmal/util/mmal_util_params.h>
-
-#include "Util.h"
-#include "MMALRenderer.h"
-#include "ServiceBroker.h"
-#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h"
-#include "filesystem/File.h"
-#include "settings/DisplaySettings.h"
-#include "settings/MediaSettings.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "threads/SingleLock.h"
-#include "utils/log.h"
-#include "utils/MathUtils.h"
-#include "cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h"
-#include "cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h"
-#include "Application.h"
-#include "platform/linux/RBP.h"
-#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
-#include "cores/VideoPlayer/Interface/Addon/TimingConstants.h"
-
-extern "C" {
-#include <libavutil/imgutils.h>
-}
-
-#define VERBOSE 0
-
-using namespace MMAL;
-
-#define CLASSNAME "CMMALBuffer"
-
-CMMALBuffer::CMMALBuffer(int id) : CVideoBuffer(id)
-{
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, static_cast<void*>(this));
-}
-
-CMMALBuffer::~CMMALBuffer()
-{
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, static_cast<void*>(this));
-}
-
-void CMMALBuffer::Unref()
-{
- if (mmal_buffer)
- {
- mmal_buffer_header_release(mmal_buffer);
- mmal_buffer = nullptr;
- }
-}
-
-void CMMALBuffer::Update()
-{
- if (mmal_buffer)
- {
- CMMALYUVBuffer *yuv = dynamic_cast<CMMALYUVBuffer *>(this);
- if (yuv)
- {
- int size = 0;
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- if (pool)
- size = pool->Size();
- mmal_buffer->alloc_size = size;
- mmal_buffer->length = size;
- CGPUMEM *gmem = yuv->GetMem();
- if (gmem)
- mmal_buffer->data = (uint8_t *)gmem->m_vc_handle;
- }
- }
-}
-
-void CMMALBuffer::SetVideoDeintMethod(std::string method)
-{
- std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool);
- if (pool)
- pool->SetVideoDeintMethod(method);
-}
-
-
-#undef CLASSNAME
-#define CLASSNAME "CMMALPool"
-
-
-void CMMALPool::Return(int id)
-{
- CSingleLock lock(m_critSection);
-
- m_all[id]->Unref();
- auto it = m_used.begin();
- while (it != m_used.end())
- {
- if (*it == id)
- {
- m_used.erase(it);
- break;
- }
- else
- ++it;
- }
- m_free.push_back(id);
- Prime();
-}
-
-CMMALPool::CMMALPool(const char *component_name, bool input, uint32_t num_buffers, uint32_t buffer_size, uint32_t encoding, MMALState state)
- : m_mmal_format(encoding), m_state(state), m_input(input)
-{
- CSingleLock lock(m_critSection);
- MMAL_STATUS_T status;
-
- status = mmal_component_create(component_name, &m_component);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to create component %s", CLASSNAME, __func__, component_name);
-
- MMAL_PORT_T *port = m_input ? m_component->input[0] : m_component->output[0];
-
- // set up initial decoded frame format - may change from this
- port->format->encoding = encoding;
-
- status = mmal_port_parameter_set_boolean(port, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, port->name, status, mmal_status_to_string(status));
-
- status = mmal_port_format_commit(port);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to commit format for %s (status=%x %s)", CLASSNAME, __func__, port->name, status, mmal_status_to_string(status));
-
- port->buffer_size = buffer_size;
- port->buffer_num = std::max(num_buffers, port->buffer_num_recommended);
-
- m_mmal_pool = mmal_port_pool_create(port, port->buffer_num, port->buffer_size);
- if (!m_mmal_pool)
- CLog::Log(LOGERROR, "%s::%s Failed to create pool for port %s", CLASSNAME, __func__, port->name);
- else
- {
- CLog::Log(LOGDEBUG, "%s::%s Created pool %p of size %d x %d for port %s", CLASSNAME, __func__,
- static_cast<void*>(m_mmal_pool), num_buffers, buffer_size, port->name);
- }
-}
-
-CMMALPool::~CMMALPool()
-{
- CSingleLock lock(m_critSection);
- MMAL_STATUS_T status;
-
- MMAL_PORT_T *port = m_input ? m_component->input[0] : m_component->output[0];
- CLog::Log(LOGDEBUG, "%s::%s Destroying pool %p for port %s", CLASSNAME, __func__,
- static_cast<void*>(m_mmal_pool), port->name);
-
- if (port && port->is_enabled)
- {
- status = mmal_port_disable(port);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to disable port %s (status=%x %s)", CLASSNAME, __func__, port->name, status, mmal_status_to_string(status));
- }
-
- if (m_component && m_component->is_enabled)
- {
- status = mmal_component_disable(m_component);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to disable component %s (status=%x %s)", CLASSNAME, __func__, m_component->name, status, mmal_status_to_string(status));
- }
-
- mmal_port_pool_destroy(port, m_mmal_pool);
-
- if (m_component)
- mmal_component_destroy(m_component);
- m_component = nullptr;
-
- m_mmal_pool = nullptr;
- for (auto buf : m_all)
- {
- delete buf;
- }
-}
-
-std::vector<CMMALPool::MMALEncodingTable> CMMALPool::mmal_encoding_table =
-{
- { AV_PIX_FMT_YUV420P, MMAL_ENCODING_I420 },
- { AV_PIX_FMT_YUVJ420P, MMAL_ENCODING_I420 },
- { AV_PIX_FMT_YUV420P10,MMAL_ENCODING_I420_16, },
- { AV_PIX_FMT_YUV420P12,MMAL_ENCODING_I420_16, },
- { AV_PIX_FMT_YUV420P14,MMAL_ENCODING_I420_16, },
- { AV_PIX_FMT_YUV420P16,MMAL_ENCODING_I420_16, },
- { AV_PIX_FMT_RGBA, MMAL_ENCODING_RGBA, },
- { AV_PIX_FMT_BGRA, MMAL_ENCODING_BGRA },
- { AV_PIX_FMT_RGB0, MMAL_ENCODING_RGBA },
- { AV_PIX_FMT_BGR0, MMAL_ENCODING_BGRA },
- { AV_PIX_FMT_RGB24, MMAL_ENCODING_RGB24 },
- { AV_PIX_FMT_BGR24, MMAL_ENCODING_BGR24 },
- { AV_PIX_FMT_RGB565, MMAL_ENCODING_RGB16 },
- { AV_PIX_FMT_RGB565LE, MMAL_ENCODING_RGB16 },
- { AV_PIX_FMT_BGR565, MMAL_ENCODING_BGR16 },
- { AV_PIX_FMT_NONE, MMAL_ENCODING_UNKNOWN },
-};
-
-
-uint32_t CMMALPool::TranslateFormat(AVPixelFormat pixfmt)
-{
- for (const auto& entry : mmal_encoding_table)
- {
- if (entry.pixfmt == pixfmt)
- return entry.encoding;
- }
- assert(0);
- return MMAL_ENCODING_UNKNOWN;
-}
-
-void CMMALPool::Configure(AVPixelFormat format, int width, int height, int alignedWidth, int alignedHeight, int size)
-{
- CSingleLock lock(m_critSection);
- if (format != AV_PIX_FMT_NONE)
- m_mmal_format = TranslateFormat(format);
- m_width = width;
- m_height = height;
- m_size = size;
- m_software = true;
- m_configured = true;
-
- if (m_mmal_format != MMAL_ENCODING_UNKNOWN)
- {
- m_geo = g_RBP.GetFrameGeometry(m_mmal_format, alignedWidth, alignedHeight);
- if (m_mmal_format != MMAL_ENCODING_YUVUV128 && m_mmal_format != MMAL_ENCODING_YUVUV64_16 )
- {
- if (alignedWidth)
- {
- m_geo.setStrideY(alignedWidth * m_geo.getBytesPerPixel());
- m_geo.setStrideC(alignedWidth * m_geo.getBytesPerPixel() >> 1);
- }
- if (alignedHeight)
- {
- m_geo.setHeightY(alignedHeight);
- m_geo.setHeightC(alignedHeight >> 1);
- }
- }
- }
- if (m_size == 0)
- m_size = m_geo.getSize();
- CLog::Log(LOGDEBUG, "%s::%s pool:%p %dx%d (%dx%d) pix:%d size:%d fmt:%.4s", CLASSNAME, __func__,
- static_cast<void*>(m_mmal_pool), width, height, alignedWidth, alignedHeight, format, size,
- (char*)&m_mmal_format);
-}
-
-void CMMALPool::Configure(AVPixelFormat format, int size)
-{
- Configure(format, 0, 0, 0, 0, size);
-}
-
-void CMMALPool::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES])
-{
- assert(m_geo.getBytesPerPixel());
- int alignedWidth = strides[0] ? strides[0] / m_geo.getBytesPerPixel() : width;
- int alignedHeight = planeOffsets[1] ? planeOffsets[1] / strides[0] : height;
- Configure(AV_PIX_FMT_NONE, width, height, alignedWidth, alignedHeight, 0);
- // libwv side-by-side UV format
- if (planeOffsets[2] - planeOffsets[1] == strides[1] >> 1)
- m_mmal_format = MMAL_ENCODING_I420_S;
-}
-
-inline bool CMMALPool::IsConfigured()
-{
- CSingleLock lock(m_critSection);
- return m_configured;
-}
-
-bool CMMALPool::IsCompatible(AVPixelFormat format, int size)
-{
- CSingleLock lock(m_critSection);
- uint32_t mmal_format = TranslateFormat(format);
- if (m_mmal_format == MMAL_ENCODING_I420_S && mmal_format == MMAL_ENCODING_I420)
- return true;
- if (m_mmal_format == mmal_format &&
- m_size == size)
- return true;
-
- return false;
-}
-
-CVideoBuffer *CMMALPool::Get()
-{
- return GetBuffer(500);
-}
-
-CMMALBuffer *CMMALPool::GetBuffer(uint32_t timeout)
-{
- MMAL_BUFFER_HEADER_T *buffer = nullptr;
- CMMALBuffer *omvb = nullptr;
- int id = -1;
- bool newbuf = false;
- CGPUMEM *gmem = nullptr;
-
- if (m_mmal_pool && m_mmal_pool->queue)
- buffer = mmal_queue_timedwait(m_mmal_pool->queue, timeout);
- CSingleLock lock(m_critSection);
- if (buffer)
- {
- mmal_buffer_header_reset(buffer);
- buffer->cmd = 0;
- buffer->offset = 0;
- buffer->flags = 0;
- buffer->user_data = 0;
-
- if (!m_free.empty())
- {
- id = m_free.front();
- m_free.pop_front();
- m_used.push_back(id);
- omvb = m_all[id];
- }
- else
- {
- newbuf = true;
- id = m_all.size();
- if (!IsSoftware())
- {
- CMMALVideoBuffer *vid = new CMMALVideoBuffer(id);
- omvb = vid;
- }
- else
- {
- CMMALYUVBuffer *yuv = new CMMALYUVBuffer(id);
- if (yuv)
- {
- assert(m_size > 0);
- gmem = yuv->Allocate(m_size, (void *)yuv);
- if (!gmem)
- {
- delete yuv;
- yuv = nullptr;
- }
- }
- omvb = yuv;
- }
- if (omvb)
- {
- m_all.push_back(omvb);
- m_used.push_back(id);
- }
- }
- if (omvb)
- {
- omvb->Acquire(GetPtr());
- omvb->m_rendered = false;
- omvb->m_state = m_state;
- buffer->user_data = omvb;
- omvb->mmal_buffer = buffer;
- omvb->Update();
- assert(omvb->Pool() == GetPtr());
- }
- }
- if (timeout > 0 && !omvb)
- {
- CLog::Log(LOGERROR, "%s::%s - failed pool:%p omvb:%p mmal:%p timeout:%d", CLASSNAME,
- __FUNCTION__, static_cast<void*>(m_mmal_pool), static_cast<void*>(omvb),
- static_cast<void*>(buffer), timeout);
- }
- else if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG,
- "%s::%s pool:%p omvb:%p mmal:%p gmem:%p new:%d id:%d to:%d %dx%d (%dx%d) size:%d "
- "pool:%p:%p enc:%.4s",
- CLASSNAME, __FUNCTION__, static_cast<void*>(m_mmal_pool), static_cast<void*>(omvb),
- static_cast<void*>(buffer), static_cast<void*>(gmem), newbuf, id, timeout, m_width,
- m_height, AlignedWidth(), AlignedHeight(), buffer ? buffer->alloc_size : 0,
- omvb ? static_cast<void*>(omvb->Pool().get()) : nullptr,
- static_cast<void*>(GetPtr().get()), (char*)&m_mmal_format);
- }
- return omvb;
-}
-
-void CMMALPool::Prime()
-{
- CSingleLock lock(m_critSection);
- CMMALBuffer *omvb;
- if (!m_mmal_pool || !m_component)
- return;
- MMAL_PORT_T *port = m_input ? m_component->input[0] : m_component->output[0];
- if (!port->is_enabled)
- return;
- while (omvb = GetBuffer(0), omvb)
- {
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(
- LOGDEBUG, "%s::%s Send omvb:%p mmal:%p from pool %p to %s len:%d cmd:%x flags:%x pool:%p",
- CLASSNAME, __func__, static_cast<void*>(omvb), static_cast<void*>(omvb->mmal_buffer),
- static_cast<void*>(m_mmal_pool), port->name, omvb->mmal_buffer->length,
- omvb->mmal_buffer->cmd, omvb->mmal_buffer->flags, static_cast<void*>(omvb->Pool().get()));
- }
- MMAL_STATUS_T status = mmal_port_send_buffer(port, omvb->mmal_buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(
- LOGERROR, "%s::%s - Failed to send omvb:%p mmal:%p from pool %p to %s (status=0%x %s)",
- CLASSNAME, __func__, static_cast<void*>(omvb), static_cast<void*>(omvb->mmal_buffer),
- static_cast<void*>(m_mmal_pool), port->name, status, mmal_status_to_string(status));
- }
- }
-}
-
-void CMMALPool::SetVideoDeintMethod(std::string method)
-{
- CSingleLock lock(m_critSection);
- if (m_processInfo)
- m_processInfo->SetVideoDeintMethod(method);
-}
-
-void CMMALPool::Released(CVideoBufferManager &videoBufferManager)
-{
- /* Create dummy component with attached pool */
- std::shared_ptr<IVideoBufferPool> pool = std::make_shared<CMMALPool>(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, false, MMAL_NUM_OUTPUT_BUFFERS, 0, MMAL_ENCODING_UNKNOWN, MMALStateFFDec);
- videoBufferManager.RegisterPool(pool);
-}
-
-#undef CLASSNAME
-#define CLASSNAME "CMMALRenderer"
-
-CRenderInfo CMMALRenderer::GetRenderInfo()
-{
- CSingleLock lock(m_sharedSection);
- CRenderInfo info;
-
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s opaque:%p", CLASSNAME, __func__, static_cast<void*>(this));
-
- info.max_buffer_size = NUM_BUFFERS;
- info.optimal_buffer_size = NUM_BUFFERS;
- info.opaque_pointer = (void *)this;
-
- return info;
-}
-
-void CMMALRenderer::vout_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG, "%s::%s omvb:%p mmal:%p dts:%.3f pts:%.3f len:%d cmd:%x flags:%x",
- CLASSNAME, __func__, static_cast<void*>(buffer->user_data),
- static_cast<void*>(buffer), buffer->dts * 1e-6, buffer->pts * 1e-6, buffer->length,
- buffer->cmd, buffer->flags);
- }
- buffer->length = 0;
- mmal_queue_put(m_queue_process, buffer);
-}
-
-static void vout_input_port_cb_static(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CMMALRenderer *mmal = reinterpret_cast<CMMALRenderer*>(port->userdata);
- mmal->vout_input_port_cb(port, buffer);
-}
-
-bool CMMALRenderer::CheckConfigurationVout(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding)
-{
- MMAL_STATUS_T status;
- bool sizeChanged = width != m_vout_width || height != m_vout_height || aligned_width != m_vout_aligned_width || aligned_height != m_vout_aligned_height;
- bool encodingChanged = !m_vout_input || !m_vout_input->format || encoding != m_vout_input->format->encoding;
-
- if (!m_vout)
- {
- /* Create video renderer */
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s CreateRenderer", CLASSNAME, __func__);
-
- status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &m_vout);
- if(status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to create vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- m_vout_input = m_vout->input[0];
-
- status = mmal_port_parameter_set_boolean(m_vout_input, MMAL_PARAMETER_NO_IMAGE_PADDING, MMAL_TRUE);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable no image padding mode on %s (status=%x %s)", CLASSNAME, __func__, m_vout_input->name, status, mmal_status_to_string(status));
-
- status = mmal_port_parameter_set_boolean(m_vout_input, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_vout_input->name, status, mmal_status_to_string(status));
-
- m_vout_input->format->type = MMAL_ES_TYPE_VIDEO;
- if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT709)
- m_vout_input->format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT709;
- else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT601)
- m_vout_input->format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT601;
- else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_240M)
- m_vout_input->format->es->video.color_space = MMAL_COLOR_SPACE_SMPTE240M;
- }
-
- if (m_vout_input && (sizeChanged || encodingChanged))
- {
- assert(m_vout_input != nullptr && m_vout_input->format != nullptr && m_vout_input->format->es != nullptr);
- CLog::Log(LOGDEBUG, "%s::%s Changing Vout dimensions from %dx%d (%dx%d) to %dx%d (%dx%d) %.4s", CLASSNAME, __func__,
- m_vout_width, m_vout_height, m_vout_aligned_width, m_vout_aligned_height, width, height, aligned_width, aligned_height, (char *)&encoding);
-
- // we need to disable port when encoding changes, but not if just resolution changes
- if (encodingChanged && m_vout_input->is_enabled)
- {
- status = mmal_port_disable(m_vout_input);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to disable vout input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- }
-
- m_vout_width = width;
- m_vout_height = height;
- m_vout_aligned_width = aligned_width;
- m_vout_aligned_height = aligned_height;
-
- m_vout_input->format->es->video.crop.width = width;
- m_vout_input->format->es->video.crop.height = height;
- m_vout_input->format->es->video.width = aligned_width;
- m_vout_input->format->es->video.height = aligned_height;
- m_vout_input->format->encoding = encoding;
-
- status = mmal_port_format_commit(m_vout_input);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to commit vout input format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- if (!m_vout_input->is_enabled)
- {
- m_vout_input->buffer_num = MMAL_NUM_OUTPUT_BUFFERS;
- m_vout_input->buffer_size = m_vout_input->buffer_size_recommended;
- m_vout_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;
-
- status = mmal_port_enable(m_vout_input, vout_input_port_cb_static);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable vout input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- }
- }
-
- if (m_vout && !m_vout->is_enabled)
- {
- status = mmal_component_enable(m_vout);
- if(status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- if (!m_queue_render && !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool("videoplayer.usedisplayasclock"))
- {
- m_queue_render = mmal_queue_create();
- CThread::Create();
- }
- }
- SetVideoRect(m_cachedSourceRect, m_cachedDestRect);
- return true;
-}
-
-CMMALRenderer::CMMALRenderer() : CThread("MMALRenderer"), m_processThread(this, "MMALProcess")
-{
- CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
- m_vout = NULL;
- m_vout_input = NULL;
- memset(m_buffers, 0, sizeof m_buffers);
- m_iFlags = 0;
- m_bConfigured = false;
- m_queue_render = nullptr;
- m_error = 0.0;
- m_fps = 0.0;
- m_lastPts = DVD_NOPTS_VALUE;
- m_frameInterval = 0.0;
- m_frameIntervalDiff = 1e5;
- m_vsync_count = ~0U;
- m_vout_width = 0;
- m_vout_height = 0;
- m_vout_aligned_width = 0;
- m_vout_aligned_height = 0;
- m_deint = NULL;
- m_deint_input = NULL;
- m_deint_output = NULL;
- m_deint_width = 0;
- m_deint_height = 0;
- m_deint_aligned_width = 0;
- m_deint_aligned_height = 0;
- m_cachedSourceRect.SetRect(0, 0, 0, 0);
- m_cachedDestRect.SetRect(0, 0, 0, 0);
- m_isPi1 = g_RBP.RaspberryPiVersion() == 1;
-
- m_queue_process = mmal_queue_create();
- m_processThread.Create();
-}
-
-CMMALRenderer::~CMMALRenderer()
-{
- CSingleLock lock(m_sharedSection);
- CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
- UnInit();
-
- if (m_queue_process)
- mmal_queue_put(m_queue_process, &m_quitpacket);
-
- {
- // leave the lock to allow other threads to exit
- CSingleExit unlock(m_sharedSection);
- m_processThread.StopThread();
- }
-
- mmal_queue_destroy(m_queue_process);
- m_queue_process = nullptr;
-}
-
-
-void CMMALRenderer::Process()
-{
- bool bStop = false;
- SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
- CLog::Log(LOGDEBUG, "%s::%s - starting", CLASSNAME, __func__);
- while (!bStop)
- {
- double dfps = CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS();
- double fps = 0.0;
- double inc = 1.0;
- g_RBP.WaitVsync();
-
- CSingleLock lock(m_sharedSection);
- // if good enough framerate measure then use it
- if (dfps > 0.0 && m_frameInterval > 0.0 && m_frameIntervalDiff * 1e-6 < 1e-3)
- {
- fps = 1e6 / m_frameInterval;
- inc = fps / dfps;
- if (fabs(inc - 1.0) < 1e-2)
- inc = 1.0;
- else if (fabs(inc - 0.5) < 1e-2)
- inc = 0.5;
- else if (fabs(inc - 24.0/60.0) < 1e-2)
- inc = 24.0/60.0;
- if (m_deint)
- inc *= 2.0;
- }
- // This algorithm is basically making the decision according to Bresenham's line algorithm. Imagine drawing a line where x-axis is display frames, and y-axis is video frames
- m_error += inc;
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - debug vsync:%d queue:%d fps:%.2f/%.2f/%.2f inc:%f diff:%f", CLASSNAME, __func__, g_RBP.LastVsync(), mmal_queue_length(m_queue_render), fps, m_fps, dfps, inc, m_error);
- // we may need to discard frames if queue length gets too high or video frame rate is above display frame rate
- while (mmal_queue_length(m_queue_render) > 2 || (mmal_queue_length(m_queue_render) > 1 && m_error > 1.0))
- {
- if (m_error > 1.0)
- m_error -= 1.0;
- MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(m_queue_render);
- if (buffer == &m_quitpacket)
- bStop = true;
- else if (buffer)
- {
- CMMALBuffer *omvb = (CMMALBuffer *)buffer->user_data;
- assert(buffer == omvb->mmal_buffer);
- omvb->Release();
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - discard omvb:%p mmal:%p vsync:%d queue:%d diff:%f",
- CLASSNAME, __func__, static_cast<void*>(omvb), static_cast<void*>(buffer),
- g_RBP.LastVsync(), mmal_queue_length(m_queue_render), m_error);
- }
- }
- // this is case where we would like to display a new frame
- if (m_error > 0.0)
- {
- m_error -= 1.0;
- MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(m_queue_render);
- if (buffer == &m_quitpacket)
- bStop = true;
- else if (buffer)
- {
- CMMALBuffer *omvb = (CMMALBuffer *)buffer->user_data;
- assert(buffer == omvb->mmal_buffer);
- CheckConfigurationVout(omvb->Width(), omvb->Height(), omvb->AlignedWidth(), omvb->AlignedHeight(), omvb->Encoding());
- MMAL_STATUS_T status = mmal_port_send_buffer(m_vout_input, buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s - Failed to send omvb:%p mmal:%p to %s (status=0%x %s)",
- CLASSNAME, __func__, static_cast<void*>(omvb), static_cast<void*>(buffer),
- m_vout_input->name, status, mmal_status_to_string(status));
- }
- }
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - omvb:%p mmal:%p vsync:%d queue:%d diff:%f", CLASSNAME,
- __func__, buffer ? static_cast<void*>(buffer->user_data) : nullptr,
- static_cast<void*>(buffer), g_RBP.LastVsync(), mmal_queue_length(m_queue_render),
- m_error);
- }
- }
- CLog::Log(LOGDEBUG, "%s::%s - stopping", CLASSNAME, __func__);
-}
-
-void CMMALRenderer::Run()
-{
- CLog::Log(LOGDEBUG, "%s::%s - starting", CLASSNAME, __func__);
- while (1)
- {
- MMAL_BUFFER_HEADER_T *buffer = mmal_queue_wait(m_queue_process);
- assert(buffer);
- if (buffer == &m_quitpacket)
- break;
- CSingleLock lock(m_sharedSection);
- bool kept = false;
-
- CMMALBuffer *omvb = (CMMALBuffer *)buffer->user_data;
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG,
- "%s::%s %s omvb:%p mmal:%p dts:%.3f pts:%.3f len:%d cmd:%x flags:%x enc:%.4s",
- CLASSNAME, __func__, omvb ? omvb->GetStateName() : "", static_cast<void*>(omvb),
- static_cast<void*>(buffer), buffer->dts * 1e-6, buffer->pts * 1e-6, buffer->length,
- buffer->cmd, buffer->flags, omvb ? (char*)&omvb->Encoding() : "");
- }
-
- assert(omvb && buffer == omvb->mmal_buffer);
- assert(buffer->cmd == 0);
- assert(!(buffer->flags & (MMAL_BUFFER_HEADER_FLAG_EOS | MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED)));
- if (m_bConfigured)
- switch (omvb->m_state)
- {
- case MMALStateHWDec:
- case MMALStateFFDec:
- {
- if (buffer->length > 0)
- {
- int yuv16 = omvb->Encoding() == MMAL_ENCODING_I420_16 || omvb->Encoding() == MMAL_ENCODING_YUVUV64_16;
- EINTERLACEMETHOD last_interlace_method = m_interlace_method;
- EINTERLACEMETHOD interlace_method = m_videoSettings.m_InterlaceMethod;
- if (interlace_method == VS_INTERLACEMETHOD_AUTO)
- {
- interlace_method = VS_INTERLACEMETHOD_MMAL_ADVANCED;
- // avoid advanced deinterlace when using software decode and HD resolution
- if ((omvb->m_state == MMALStateFFDec || m_isPi1) && omvb->Width() * omvb->Height() > 720*576)
- interlace_method = VS_INTERLACEMETHOD_MMAL_BOB;
- }
- bool interlace = (omvb->mmal_buffer->flags & MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED) ? true:false;
-
- // advanced deinterlace requires 3 frames of context so disable when showing stills
- if (omvb->m_stills)
- {
- if (interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED)
- interlace_method = VS_INTERLACEMETHOD_MMAL_BOB;
- if (interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF)
- interlace_method = VS_INTERLACEMETHOD_MMAL_BOB_HALF;
- }
-
- // we don't keep up when running at 60fps in the background so switch to half rate
- if (!CServiceBroker::GetWinSystem()->GetGfxContext().IsFullScreenVideo())
- {
- if (interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED)
- interlace_method = VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF;
- if (interlace_method == VS_INTERLACEMETHOD_MMAL_BOB)
- interlace_method = VS_INTERLACEMETHOD_MMAL_BOB_HALF;
- }
-
- if (interlace_method == VS_INTERLACEMETHOD_NONE && !yuv16)
- {
- if (m_deint_input)
- DestroyDeinterlace();
- }
-
- if (yuv16)
- interlace_method = VS_INTERLACEMETHOD_NONE;
-
- if (yuv16 || (interlace_method != VS_INTERLACEMETHOD_NONE && (m_deint_input || interlace)))
- CheckConfigurationDeint(omvb->Width(), omvb->Height(), omvb->AlignedWidth(), omvb->AlignedHeight(), omvb->Encoding(), interlace_method, omvb->BitsPerPixel());
-
- if (!m_deint_input)
- m_interlace_method = VS_INTERLACEMETHOD_NONE;
-
- if (last_interlace_method == m_interlace_method)
- ;
- else if (m_interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED)
- omvb->SetVideoDeintMethod("adv(x2)");
- else if (m_interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF)
- omvb->SetVideoDeintMethod("adv(x1)");
- else if (m_interlace_method == VS_INTERLACEMETHOD_MMAL_BOB)
- omvb->SetVideoDeintMethod("bob(x2)");
- else if (m_interlace_method == VS_INTERLACEMETHOD_MMAL_BOB_HALF)
- omvb->SetVideoDeintMethod("bob(x1)");
- else
- omvb->SetVideoDeintMethod("none");
-
- if (m_deint_input)
- {
- MMAL_STATUS_T status = mmal_port_send_buffer(m_deint_input, omvb->mmal_buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s - Failed to send omvb:%p mmal:%p to %s (status=0%x %s)",
- CLASSNAME, __func__, static_cast<void*>(omvb),
- static_cast<void*>(omvb->mmal_buffer), m_deint_input->name, status,
- mmal_status_to_string(status));
- }
- else
- kept = true;
- }
- else if (m_queue_render)
- {
- mmal_queue_put(m_queue_render, omvb->mmal_buffer);
- kept = true;
- }
- else
- {
- CheckConfigurationVout(omvb->Width(), omvb->Height(), omvb->AlignedWidth(), omvb->AlignedHeight(), omvb->Encoding());
- if (m_vout_input)
- {
- MMAL_STATUS_T status = mmal_port_send_buffer(m_vout_input, omvb->mmal_buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s - Failed to send omvb:%p mmal:%p to %s (status=0%x %s)",
- CLASSNAME, __func__, static_cast<void*>(omvb),
- static_cast<void*>(omvb->mmal_buffer), m_vout_input->name, status,
- mmal_status_to_string(status));
- }
- else
- kept = true;
- }
- }
- }
- break;
- }
- case MMALStateDeint:
- {
- if (buffer->length > 0)
- {
- if (m_queue_render)
- {
- mmal_queue_put(m_queue_render, buffer);
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- CLog::Log(LOGDEBUG, "%s::%s send %p to m_queue_render", CLASSNAME, __func__, static_cast<void*>(omvb));
- kept = true;
- }
- else
- {
- CheckConfigurationVout(omvb->Width(), omvb->Height(), omvb->AlignedWidth(), omvb->AlignedHeight(), omvb->Encoding());
- if (m_vout_input)
- {
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- CLog::Log(LOGDEBUG, "%s::%s send %p to m_vout_input", CLASSNAME, __func__, static_cast<void*>(omvb));
- MMAL_STATUS_T status = mmal_port_send_buffer(m_vout_input, buffer);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s - Failed to send omvb:%p mmal%:p to %s (status=0%x %s)",
- CLASSNAME, __func__, static_cast<void*>(omvb), static_cast<void*>(buffer),
- m_vout_input->name, status, mmal_status_to_string(status));
- }
- else
- kept = true;
- }
- }
- }
- break;
- }
- default: assert(0); break;
- }
- if (!kept)
- {
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(
- LOGDEBUG,
- "%s::%s %s Not kept: omvb:%p mmal:%p dts:%.3f pts:%.3f len:%d cmd:%x flags:%x enc:%.4s",
- CLASSNAME, __func__, omvb ? omvb->GetStateName() : "", static_cast<void*>(omvb),
- static_cast<void*>(buffer), buffer->dts * 1e-6, buffer->pts * 1e-6, buffer->length,
- buffer->cmd, buffer->flags, omvb ? (char*)&omvb->Encoding() : "");
- }
- if (omvb)
- omvb->Release();
- else
- {
- mmal_buffer_header_reset(buffer);
- buffer->cmd = 0;
- mmal_buffer_header_release(buffer);
- }
- }
- }
- CLog::Log(LOGDEBUG, "%s::%s - stopping", CLASSNAME, __func__);
-}
-
-void CMMALRenderer::UpdateFramerateStats(double pts)
-{
- double diff = 0.0;
- if (m_lastPts != DVD_NOPTS_VALUE && pts != DVD_NOPTS_VALUE && pts - m_lastPts > 0.0 && pts - m_lastPts < DVD_SEC_TO_TIME(1./20.0))
- {
- diff = pts - m_lastPts;
- if (m_frameInterval == 0.0)
- m_frameInterval = diff;
- else if (diff > 0.0)
- {
- m_frameIntervalDiff = m_frameIntervalDiff * 0.9 + 0.1 * fabs(m_frameInterval - diff);
- m_frameInterval = m_frameInterval * 0.9 + diff * 0.1;
- }
- }
- if (pts != DVD_NOPTS_VALUE)
- m_lastPts = pts;
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- CLog::Log(LOGDEBUG, "%s::%s pts:%.3f diff:%.3f m_frameInterval:%.6f m_frameIntervalDiff:%.6f", CLASSNAME, __func__, pts*1e-6, diff * 1e-6 , m_frameInterval * 1e-6, m_frameIntervalDiff *1e-6);
-}
-
-void CMMALRenderer::AddVideoPicture(const VideoPicture& pic, int id)
-{
- CMMALBuffer *buffer = dynamic_cast<CMMALBuffer*>(pic.videoBuffer);
- assert(buffer);
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG, "%s::%s MMAL - %p (%p) %i", CLASSNAME, __func__, static_cast<void*>(buffer),
- static_cast<void*>(buffer->mmal_buffer), id);
- }
-
- assert(!m_buffers[id]);
- buffer->Acquire();
- m_buffers[id] = buffer;
- UpdateFramerateStats(pic.pts);
-}
-
-bool CMMALRenderer::Configure(const VideoPicture &picture, float fps, unsigned int orientation)
-{
- CSingleLock lock(m_sharedSection);
- ReleaseBuffers();
-
- if (picture.videoBuffer)
- m_format = picture.videoBuffer->GetFormat();
- m_sourceWidth = picture.iWidth;
- m_sourceHeight = picture.iHeight;
- m_renderOrientation = orientation;
-
- m_iFlags = GetFlagsChromaPosition(picture.chroma_position) |
- GetFlagsColorPrimaries(picture.color_primaries) |
- GetFlagsStereoMode(picture.stereoMode);
-
- m_fps = fps;
- m_error = 0.0;
- m_lastPts = DVD_NOPTS_VALUE;
- m_frameInterval = 0.0;
- m_frameIntervalDiff = 1e5;
-
- // cause SetVideoRect to trigger - needed after a hdmi mode change
- m_src_rect.SetRect(0, 0, 0, 0);
- m_dst_rect.SetRect(0, 0, 0, 0);
-
- CLog::Log(LOGDEBUG, "%s::%s - %dx%d->%dx%d@%.2f flags:%x format:%d orient:%d", CLASSNAME, __func__, picture.iWidth, picture.iHeight, picture.iDisplayWidth, picture.iDisplayHeight, fps, m_iFlags, m_format, orientation);
-
- // calculate the input frame aspect ratio
- CalculateFrameAspectRatio(picture.iDisplayWidth, picture.iDisplayHeight);
- SetViewMode(m_videoSettings.m_ViewMode);
- ManageRenderArea();
-
- m_bConfigured = true;
- return true;
-}
-
-void CMMALRenderer::ReleaseBuffer(int id)
-{
- CSingleLock lock(m_sharedSection);
- CMMALBuffer *omvb = m_buffers[id];
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG, "%s::%s - MMAL: source:%d omvb:%p mmal:%p", CLASSNAME, __func__, id,
- static_cast<void*>(omvb), omvb ? static_cast<void*>(omvb->mmal_buffer) : nullptr);
- }
- if (m_buffers[id])
- m_buffers[id]->Release();
- m_buffers[id] = nullptr;
-}
-
-bool CMMALRenderer::Flush(bool saveBuffers)
-{
- CSingleLock lock(m_sharedSection);
- CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
- if (m_vout_input)
- mmal_port_flush(m_vout_input);
- ReleaseBuffers();
-
- return false;
-}
-
-void CMMALRenderer::Update()
-{
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s", CLASSNAME, __func__);
- if (!m_bConfigured) return;
- ManageRenderArea();
-}
-
-void CMMALRenderer::RenderUpdate(int index, int index2, bool clear, unsigned int flags, unsigned int alpha)
-{
- CSingleLock lock(m_sharedSection);
- CMMALBuffer *omvb = nullptr;
-
- if (!m_bConfigured)
- {
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s - not configured: clear:%d flags:%x alpha:%d source:%d", CLASSNAME, __func__, clear, flags, alpha, index);
- goto exit;
- }
-
- omvb = m_buffers[index];
-
- if (CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoView() != RENDER_STEREO_VIEW_RIGHT)
- {
- ManageRenderArea();
- CRect view;
- CBaseRenderer::GetVideoRect(m_cachedSourceRect, m_cachedDestRect, view);
- }
-
- // we only want to upload frames once
- if (omvb && omvb->m_rendered)
- {
- CLog::Log(
- LOGDEBUG, LOGVIDEO,
- "%s::%s - MMAL: clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p mflags:%x skipping",
- CLASSNAME, __func__, clear, flags, alpha, index, static_cast<void*>(omvb),
- static_cast<void*>(omvb->mmal_buffer), omvb->mmal_buffer->flags);
- SetVideoRect(m_cachedSourceRect, m_cachedDestRect);
- goto exit;
- }
-
- if (omvb && omvb->m_state == MMALStateBypass)
- {
- // dummy buffer from omxplayer
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG, "%s::%s - OMX: clear:%d flags:%x alpha:%d source:%d omvb:%p", CLASSNAME,
- __func__, clear, flags, alpha, index, static_cast<void*>(omvb));
- }
- }
- else if (omvb && omvb->mmal_buffer)
- {
- if (flags & RENDER_FLAG_TOP)
- omvb->mmal_buffer->flags |= MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED | MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST;
- else if (flags & RENDER_FLAG_BOT)
- omvb->mmal_buffer->flags |= MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED;
- CLog::Log(LOGDEBUG, LOGVIDEO,
- "%s::%s - MMAL: clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p mflags:%x "
- "len:%d data:%p enc:%.4s",
- CLASSNAME, __func__, clear, flags, alpha, index, static_cast<void*>(omvb),
- static_cast<void*>(omvb->mmal_buffer), omvb->mmal_buffer->flags,
- omvb->mmal_buffer->length, static_cast<void*>(omvb->mmal_buffer->data),
- (char*)&omvb->Encoding());
- assert(omvb->mmal_buffer && omvb->mmal_buffer->data && omvb->mmal_buffer->length);
- omvb->Acquire();
- omvb->m_rendered = true;
- assert(omvb->mmal_buffer->user_data == omvb);
- mmal_queue_put(m_queue_process, omvb->mmal_buffer);
- }
- else
- {
- CLog::Log(
- LOGDEBUG,
- "%s::%s - MMAL: No buffer to update clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p",
- CLASSNAME, __func__, clear, flags, alpha, index, static_cast<void*>(omvb),
- omvb ? static_cast<void*>(omvb->mmal_buffer) : nullptr);
- }
-
-exit:
- lock.Leave();
- uint32_t v = g_RBP.WaitVsync(m_vsync_count);
- // allow a frame of slop
- if (m_vsync_count == ~0U || !(v == m_vsync_count))
- {
- CLog::Log(LOGDEBUG, "%s::%s - vsync %d (+%d)", CLASSNAME, __func__, m_vsync_count, v - m_vsync_count);
- m_vsync_count = v + 1;
- }
- else
- m_vsync_count++;
-}
-
-void CMMALRenderer::ReleaseBuffers()
-{
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
- for (int i=0; i<NUM_BUFFERS; i++)
- ReleaseBuffer(i);
-}
-
-void CMMALRenderer::UnInitMMAL()
-{
- CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
-
- if (m_queue_render)
- {
- mmal_queue_put(m_queue_render, &m_quitpacket);
- {
- // leave the lock to allow other threads to exit
- CSingleExit unlock(m_sharedSection);
- StopThread(true);
- }
- mmal_queue_destroy(m_queue_render);
- m_queue_render = nullptr;
- }
-
- if (m_vout)
- {
- mmal_component_disable(m_vout);
- }
-
- if (m_vout_input)
- {
- mmal_port_flush(m_vout_input);
- mmal_port_disable(m_vout_input);
- }
-
- ReleaseBuffers();
-
- m_vout_input = NULL;
-
- if (m_vout)
- {
- mmal_component_release(m_vout);
- m_vout = NULL;
- }
-
- m_src_rect.SetRect(0, 0, 0, 0);
- m_dst_rect.SetRect(0, 0, 0, 0);
- m_video_stereo_mode = RENDER_STEREO_MODE_OFF;
- m_display_stereo_mode = RENDER_STEREO_MODE_OFF;
- m_StereoInvert = false;
- m_vout_width = 0;
- m_vout_height = 0;
- m_vout_aligned_width = 0;
- m_vout_aligned_height = 0;
-}
-
-void CMMALRenderer::UnInit()
-{
- CSingleLock lock(m_sharedSection);
- m_bConfigured = false;
- DestroyDeinterlace();
- UnInitMMAL();
-}
-
-bool CMMALRenderer::RenderCapture(CRenderCapture* capture)
-{
- if (!m_bConfigured)
- return false;
-
- CLog::Log(LOGDEBUG, "%s::%s - %p", CLASSNAME, __func__, static_cast<void*>(capture));
-
- capture->BeginRender();
- capture->EndRender();
-
- return true;
-}
-
-//********************************************************************************************************
-// YV12 Texture creation, deletion, copying + clearing
-//********************************************************************************************************
-
-bool CMMALRenderer::Supports(ERENDERFEATURE feature)
-{
- if (feature == RENDERFEATURE_STRETCH ||
- feature == RENDERFEATURE_ZOOM ||
- feature == RENDERFEATURE_ROTATION ||
- feature == RENDERFEATURE_VERTICAL_SHIFT ||
- feature == RENDERFEATURE_PIXEL_RATIO)
- return true;
-
- return false;
-}
-
-bool CMMALRenderer::Supports(ESCALINGMETHOD method)
-{
- return false;
-}
-
-void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect)
-{
- CSingleLock lock(m_sharedSection);
-
- if (!m_vout_input)
- return;
-
- CRect SrcRect = InSrcRect, DestRect = InDestRect;
- RENDER_STEREO_MODE video_stereo_mode = (m_iFlags & CONF_FLAGS_STEREO_MODE_SBS) ? RENDER_STEREO_MODE_SPLIT_VERTICAL :
- (m_iFlags & CONF_FLAGS_STEREO_MODE_TAB) ? RENDER_STEREO_MODE_SPLIT_HORIZONTAL : RENDER_STEREO_MODE_OFF;
- bool stereo_invert = (m_iFlags & CONF_FLAGS_STEREO_CADANCE_RIGHT_LEFT) ? true : false;
- RENDER_STEREO_MODE display_stereo_mode = CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode();
-
- // ignore video stereo mode when 3D display mode is disabled
- if (display_stereo_mode == RENDER_STEREO_MODE_OFF)
- video_stereo_mode = RENDER_STEREO_MODE_OFF;
-
- // fix up transposed video
- if (m_renderOrientation == 90 || m_renderOrientation == 270)
- {
- float newWidth, newHeight;
- float aspectRatio = GetAspectRatio();
- // clamp width if too wide
- if (DestRect.Height() > DestRect.Width())
- {
- newWidth = DestRect.Width(); // clamp to the width of the old dest rect
- newHeight = newWidth * aspectRatio;
- }
- else // else clamp to height
- {
- newHeight = DestRect.Height(); // clamp to the height of the old dest rect
- newWidth = newHeight / aspectRatio;
- }
-
- // calculate the center point of the view and offsets
- float centerX = DestRect.x1 + DestRect.Width() * 0.5f;
- float centerY = DestRect.y1 + DestRect.Height() * 0.5f;
- float diffX = newWidth * 0.5f;
- float diffY = newHeight * 0.5f;
-
- DestRect.x1 = centerX - diffX;
- DestRect.x2 = centerX + diffX;
- DestRect.y1 = centerY - diffY;
- DestRect.y2 = centerY + diffY;
- }
-
- // check if destination rect or video view mode has changed
- if (!(m_dst_rect != DestRect) && !(m_src_rect != SrcRect) && m_video_stereo_mode == video_stereo_mode && m_display_stereo_mode == display_stereo_mode && m_StereoInvert == stereo_invert)
- return;
-
- CLog::Log(LOGDEBUG, "%s::%s %d,%d,%d,%d -> %d,%d,%d,%d (o:%d v:%d d:%d i:%d)", CLASSNAME, __func__,
- (int)SrcRect.x1, (int)SrcRect.y1, (int)SrcRect.x2, (int)SrcRect.y2,
- (int)DestRect.x1, (int)DestRect.y1, (int)DestRect.x2, (int)DestRect.y2,
- m_renderOrientation, video_stereo_mode, display_stereo_mode, stereo_invert);
-
- m_src_rect = SrcRect;
- m_dst_rect = DestRect;
- m_video_stereo_mode = video_stereo_mode;
- m_display_stereo_mode = display_stereo_mode;
- m_StereoInvert = stereo_invert;
-
- // might need to scale up m_dst_rect to display size as video decodes
- // to separate video plane that is at display size.
- RESOLUTION res = CServiceBroker::GetWinSystem()->GetGfxContext().GetVideoResolution();
- CRect gui(0, 0, CDisplaySettings::GetInstance().GetResolutionInfo(res).iWidth, CDisplaySettings::GetInstance().GetResolutionInfo(res).iHeight);
- CRect display(0, 0, CDisplaySettings::GetInstance().GetResolutionInfo(res).iScreenWidth, CDisplaySettings::GetInstance().GetResolutionInfo(res).iScreenHeight);
-
- if (display_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
- {
- float width = DestRect.x2 - DestRect.x1;
- DestRect.x1 *= 2.0f;
- DestRect.x2 = DestRect.x1 + 2.0f * width;
- }
- else if (display_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
- {
- float height = DestRect.y2 - DestRect.y1;
- DestRect.y1 *= 2.0f;
- DestRect.y2 = DestRect.y1 + 2.0f * height;
- }
-
- if (gui != display)
- {
- float xscale = display.Width() / gui.Width();
- float yscale = display.Height() / gui.Height();
- DestRect.x1 *= xscale;
- DestRect.x2 *= xscale;
- DestRect.y1 *= yscale;
- DestRect.y2 *= yscale;
- }
-
- MMAL_DISPLAYREGION_T region;
- memset(&region, 0, sizeof region);
-
- region.set = MMAL_DISPLAY_SET_DEST_RECT|MMAL_DISPLAY_SET_SRC_RECT|MMAL_DISPLAY_SET_FULLSCREEN|MMAL_DISPLAY_SET_NOASPECT|MMAL_DISPLAY_SET_MODE|MMAL_DISPLAY_SET_TRANSFORM;
- region.dest_rect.x = lrintf(DestRect.x1);
- region.dest_rect.y = lrintf(DestRect.y1);
- region.dest_rect.width = lrintf(DestRect.Width());
- region.dest_rect.height = lrintf(DestRect.Height());
-
- region.src_rect.x = lrintf(SrcRect.x1);
- region.src_rect.y = lrintf(SrcRect.y1);
- region.src_rect.width = lrintf(SrcRect.Width());
- region.src_rect.height = lrintf(SrcRect.Height());
-
- region.fullscreen = MMAL_FALSE;
- region.noaspect = MMAL_TRUE;
- region.mode = MMAL_DISPLAY_MODE_LETTERBOX;
-
- if (m_renderOrientation == 90)
- region.transform = MMAL_DISPLAY_ROT90;
- else if (m_renderOrientation == 180)
- region.transform = MMAL_DISPLAY_ROT180;
- else if (m_renderOrientation == 270)
- region.transform = MMAL_DISPLAY_ROT270;
- else
- region.transform = MMAL_DISPLAY_ROT0;
-
- if (m_video_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
- region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_TB);
- else if (m_video_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
- region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_SBS);
- else
- region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_MONO);
-
- if (m_StereoInvert)
- region.transform = (MMAL_DISPLAYTRANSFORM_T)(region.transform | DISPMANX_STEREOSCOPIC_INVERT);
-
- MMAL_STATUS_T status = mmal_util_set_display_region(m_vout_input, &region);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to set display region (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
-
- CLog::Log(LOGDEBUG, "%s::%s %d,%d,%d,%d -> %d,%d,%d,%d t:%x", CLASSNAME, __func__,
- region.src_rect.x, region.src_rect.y, region.src_rect.width, region.src_rect.height,
- region.dest_rect.x, region.dest_rect.y, region.dest_rect.width, region.dest_rect.height, region.transform);
-}
-
-void CMMALRenderer::deint_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG, "%s::%s omvb:%p mmal:%p dts:%.3f pts:%.3f len:%d cmd:%x flags:%x",
- CLASSNAME, __func__, static_cast<void*>(buffer->user_data),
- static_cast<void*>(buffer), buffer->dts * 1e-6, buffer->pts * 1e-6, buffer->length,
- buffer->cmd, buffer->flags);
- }
- mmal_queue_put(m_queue_process, buffer);
-}
-
-static void deint_input_port_cb_static(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CMMALRenderer *mmal = reinterpret_cast<CMMALRenderer*>(port->userdata);
- mmal->deint_input_port_cb(port, buffer);
-}
-
-void CMMALRenderer::deint_output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- if (VERBOSE && CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
- {
- CLog::Log(LOGDEBUG, "%s::%s omvb:%p mmal:%p dts:%.3f pts:%.3f len:%d cmd:%x flags:%x",
- CLASSNAME, __func__, static_cast<void*>(buffer->user_data),
- static_cast<void*>(buffer), buffer->dts * 1e-6, buffer->pts * 1e-6, buffer->length,
- buffer->cmd, buffer->flags);
- }
- mmal_queue_put(m_queue_process, buffer);
-}
-
-static void deint_output_port_cb_static(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- CMMALRenderer *mmal = reinterpret_cast<CMMALRenderer*>(port->userdata);
- mmal->deint_output_port_cb(port, buffer);
-}
-
-void CMMALRenderer::DestroyDeinterlace()
-{
- MMAL_STATUS_T status;
-
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s", CLASSNAME, __func__);
-
- // (lazily) destroy pool first so new buffers aren't allocated when flushing
- m_deint_output_pool = nullptr;
-
- if (m_deint_input && m_deint_input->is_enabled)
- {
- status = mmal_port_disable(m_deint_input);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to disable deinterlace input port(status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- }
- m_deint_input = nullptr;
- if (m_deint_output && m_deint_output->is_enabled)
- {
- status = mmal_port_disable(m_deint_output);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to disable deinterlace output port(status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- }
- m_deint_output = nullptr;
- m_interlace_method = VS_INTERLACEMETHOD_MAX;
- m_deint_width = 0;
- m_deint_height = 0;
- m_deint_aligned_width = 0;
- m_deint_aligned_height = 0;
- m_deint = nullptr;
-}
-
-bool CMMALRenderer::CheckConfigurationDeint(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding, EINTERLACEMETHOD interlace_method, int bitsPerPixel)
-{
- MMAL_STATUS_T status;
- bool sizeChanged = width != m_deint_width || height != m_deint_height || aligned_width != m_deint_aligned_width || aligned_height != m_deint_aligned_height;
- bool deinterlaceChanged = interlace_method != m_interlace_method;
- bool encodingChanged = !m_deint_input || !m_deint_input->format || m_deint_input->format->encoding != encoding;
- bool advanced_deinterlace = interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED || interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF;
- bool half_framerate = interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF || interlace_method == VS_INTERLACEMETHOD_MMAL_BOB_HALF;
- uint32_t output_encoding = advanced_deinterlace ? MMAL_ENCODING_YUVUV128 : MMAL_ENCODING_I420;
- const char *component = interlace_method == VS_INTERLACEMETHOD_NONE ? "vc.ril.isp" : "vc.ril.image_fx";
-
- if (!m_bConfigured)
- {
- CLog::Log(LOGDEBUG, "%s::%s Unconfigured", CLASSNAME, __func__);
- return false;
- }
-
- if (!m_deint)
- {
- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s CreateDeinterlace", CLASSNAME, __func__);
-
- /* Create deinterlace component with attached pool */
- m_deint_output_pool = std::make_shared<CMMALPool>(component, false, 3, 0, output_encoding, MMALStateDeint);
- if (!m_deint_output_pool)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to create pool for deint output", CLASSNAME, __func__);
- return false;
- }
-
- m_deint = m_deint_output_pool->GetComponent();
- m_deint_output = m_deint->output[0];
- m_deint_input = m_deint->input[0];
-
- status = mmal_port_parameter_set_boolean(m_deint_input, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_deint_input->name, status, mmal_status_to_string(status));
- }
-
- if (m_deint_input && (sizeChanged || deinterlaceChanged || encodingChanged))
- {
- assert(m_deint_input != nullptr && m_deint_input->format != nullptr && m_deint_input->format->es != nullptr);
- CLog::Log(LOGDEBUG, "%s::%s Changing Deint dimensions from %dx%d (%dx%d) to %dx%d (%dx%d) %.4s->%.4s mode %d->%d bpp:%d", CLASSNAME, __func__,
- m_deint_input->format->es->video.crop.width, m_deint_input->format->es->video.crop.height,
- m_deint_input->format->es->video.width, m_deint_input->format->es->video.height, width, height, aligned_width, aligned_height,
- (char *)&m_deint_input->format->encoding, (char *)&encoding, m_interlace_method, interlace_method, bitsPerPixel);
-
- // we need to disable port when parameters change
- if (m_deint_input && m_deint_input->is_enabled)
- {
- status = mmal_port_disable(m_deint_input);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to disable deint input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- }
- }
-
- if (m_deint_output && (sizeChanged || deinterlaceChanged || encodingChanged))
- {
- if (m_deint_output && m_deint_output->is_enabled)
- {
- status = mmal_port_disable(m_deint_output);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to disable deint output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- }
- }
-
- if (m_deint_input && (sizeChanged || deinterlaceChanged || encodingChanged))
- {
- m_deint_width = width;
- m_deint_height = height;
- m_deint_aligned_width = aligned_width;
- m_deint_aligned_height = aligned_height;
-
- m_deint_input->format->es->video.crop.width = width;
- m_deint_input->format->es->video.crop.height = height;
- m_deint_input->format->es->video.width = aligned_width;
- m_deint_input->format->es->video.height = aligned_height;
- m_deint_input->format->encoding = encoding;
-
- status = mmal_port_format_commit(m_deint_input);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to commit deint input format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- if (!m_deint_input->is_enabled)
- {
- m_deint_input->buffer_num = MMAL_NUM_OUTPUT_BUFFERS;
- m_deint_input->buffer_size = m_deint_input->buffer_size_recommended;
- m_deint_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;
-
- status = mmal_port_enable(m_deint_input, deint_input_port_cb_static);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable deint input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- }
- }
-
-
- if (m_deint_output && (sizeChanged || deinterlaceChanged || encodingChanged))
- {
- if (interlace_method != VS_INTERLACEMETHOD_NONE)
- {
- MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = {{MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param)},
- advanced_deinterlace ? MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV : MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST, 4, {5, 0, half_framerate, 1 }};
-
- status = mmal_port_parameter_set(m_deint_output, &imfx_param.hdr);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to set deinterlace parameters (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- // Image_fx assumed 3 frames of context. simple deinterlace doesn't require this
- status = mmal_port_parameter_set_uint32(m_deint_input, MMAL_PARAMETER_EXTRA_BUFFERS, 6 - 5 + advanced_deinterlace ? 2:0);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_deint_input->name, status, mmal_status_to_string(status));
- }
- else
- {
- // We need to scale the YUV to 16-bit
- status = mmal_port_parameter_set_int32(m_deint_input, MMAL_PARAMETER_CCM_SHIFT, 16-bitsPerPixel-1);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to configure MMAL_PARAMETER_CCM_SHIFT on %s (status=%x %s)", CLASSNAME, __func__, m_deint_input->name, status, mmal_status_to_string(status));
- status = mmal_port_parameter_set_uint32(m_deint_output, MMAL_PARAMETER_OUTPUT_SHIFT, 1);
- if (status != MMAL_SUCCESS)
- CLog::Log(LOGERROR, "%s::%s Failed to configure MMAL_PARAMETER_OUTPUT_SHIFT on %s (status=%x %s)", CLASSNAME, __func__, m_deint_output->name, status, mmal_status_to_string(status));
- }
- }
-
- if (m_deint_output && (sizeChanged || deinterlaceChanged || encodingChanged))
- {
- m_deint_output->format->es->video.crop.width = width;
- m_deint_output->format->es->video.crop.height = height;
- m_deint_output->format->es->video.width = ALIGN_UP(width, 32);
- m_deint_output->format->es->video.height = ALIGN_UP(height, 16);
- m_deint_output->format->encoding = output_encoding;
-
- status = mmal_port_format_commit(m_deint_output);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to commit deint output format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
-
- if (!m_deint_output->is_enabled)
- {
- m_deint_output->buffer_num = 3;
- m_deint_output->buffer_size = m_deint_output->buffer_size_recommended;
- m_deint_output->userdata = (struct MMAL_PORT_USERDATA_T *)this;
-
- status = mmal_port_enable(m_deint_output, deint_output_port_cb_static);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable deint output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
- return false;
- }
- }
- if (m_deint_output_pool)
- m_deint_output_pool->Configure(AV_PIX_FMT_NONE,
- m_deint_output->format->es->video.crop.width, m_deint_output->format->es->video.crop.height,
- m_deint_output->format->es->video.width, m_deint_output->format->es->video.height, m_deint_output->buffer_size);
- }
-
- if (m_deint && !m_deint->is_enabled)
- {
- status = mmal_component_enable(m_deint);
- if (status != MMAL_SUCCESS)
- {
- CLog::Log(LOGERROR, "%s::%s Failed to enable deinterlacer component %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status));
- return false;
- }
- }
- m_interlace_method = interlace_method;
-
- // give buffers to deint
- if (m_deint_output_pool)
- m_deint_output_pool->Prime();
- return true;
-}
-
-CBaseRenderer* CMMALRenderer::Create(CVideoBuffer *buffer)
-{
- return new CMMALRenderer();
-}
-
-bool CMMALRenderer::Register()
-{
- VIDEOPLAYER::CRendererFactory::RegisterRenderer("mmal", CMMALRenderer::Create);
- return true;
-}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h
deleted file mode 100644
index 4b77f90589..0000000000
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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 "../BaseRenderer.h"
-#include "../RenderCapture.h"
-#include "../RenderFlags.h"
-#include "cores/VideoPlayer/DVDStreamInfo.h"
-#include "cores/VideoSettings.h"
-#include "threads/IRunnable.h"
-#include "threads/Thread.h"
-#include "utils/Geometry.h"
-#include "windowing/GraphicContext.h"
-
-#include <vector>
-
-#include <interface/mmal/mmal.h>
-
-// worst case number of buffers. 12 for decoder. 8 for multi-threading in ffmpeg. NUM_BUFFERS for renderer.
-// Note, generally these won't necessarily result in allocated pictures
-#define MMAL_NUM_OUTPUT_BUFFERS (12 + 8 + NUM_BUFFERS)
-
-struct VideoPicture;
-class CProcessInfo;
-
-namespace MMAL {
-
-class CMMALBuffer;
-
-enum MMALState { MMALStateNone, MMALStateHWDec, MMALStateFFDec, MMALStateDeint, MMALStateBypass, };
-
-class CMMALPool : public IVideoBufferPool
-{
-public:
- CMMALPool(const char *component_name, bool input, uint32_t num_buffers, uint32_t buffer_size, uint32_t encoding, MMALState state);
- ~CMMALPool();
-
- virtual CVideoBuffer* Get() override;
- virtual void Return(int id) override;
- virtual void Configure(AVPixelFormat format, int size) override;
- virtual bool IsConfigured() override;
- virtual bool IsCompatible(AVPixelFormat format, int size) override;
-
- void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]);
- MMAL_COMPONENT_T *GetComponent() { return m_component; }
- CMMALBuffer *GetBuffer(uint32_t timeout);
- void Prime();
- void SetProcessInfo(CProcessInfo *processInfo) { m_processInfo = processInfo; }
- void Configure(AVPixelFormat format, int width, int height, int alignedWidth, int alignedHeight, int size);
- bool IsSoftware() { return m_software; }
- void SetVideoDeintMethod(std::string method);
- static uint32_t TranslateFormat(AVPixelFormat pixfmt);
- virtual int Width() { return m_width; }
- virtual int Height() { return m_height; }
- virtual int AlignedWidth() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 || m_geo.getBytesPerPixel() == 0 ? 0 : m_geo.getStrideY() / m_geo.getBytesPerPixel(); }
- virtual int AlignedHeight() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 ? 0 : m_geo.getHeightY(); }
- virtual int BitsPerPixel() { return m_geo.getBitsPerPixel(); }
- virtual uint32_t &Encoding() { return m_mmal_format; }
- virtual int Size() { return m_size; }
- AVRpiZcFrameGeometry &GetGeometry() { return m_geo; }
- virtual void Released(CVideoBufferManager &videoBufferManager);
-
-protected:
- int m_width = 0;
- int m_height = 0;
- bool m_configured = false;
- CCriticalSection m_critSection;
-
- std::vector<CMMALBuffer*> m_all;
- std::deque<int> m_used;
- std::deque<int> m_free;
-
- int m_size = 0;
- uint32_t m_mmal_format = 0;
- bool m_software = false;
- CProcessInfo *m_processInfo = nullptr;
- MMALState m_state;
- bool m_input;
- MMAL_POOL_T *m_mmal_pool;
- MMAL_COMPONENT_T *m_component;
- AVRpiZcFrameGeometry m_geo;
- struct MMALEncodingTable
- {
- AVPixelFormat pixfmt;
- uint32_t encoding;
- };
- static std::vector<MMALEncodingTable> mmal_encoding_table;
-};
-
-// a generic mmal video frame. May be overridden as either software or hardware decoded buffer
-class CMMALBuffer : public CVideoBuffer
-{
-public:
- CMMALBuffer(int id);
- virtual ~CMMALBuffer();
- MMAL_BUFFER_HEADER_T *mmal_buffer = nullptr;
- float m_aspect_ratio = 0.0f;
- MMALState m_state = MMALStateNone;
- bool m_rendered = false;
- bool m_stills = false;
-
- virtual void Unref();
- virtual std::shared_ptr<CMMALPool> Pool() { return std::dynamic_pointer_cast<CMMALPool>(m_pool); };
- virtual int Width() { return Pool()->Width(); }
- virtual int Height() { return Pool()->Height(); }
- virtual int AlignedWidth() { return Pool()->AlignedWidth(); }
- virtual int AlignedHeight() { return Pool()->AlignedHeight(); }
- virtual uint32_t &Encoding() { return Pool()->Encoding(); }
- virtual int BitsPerPixel() { return Pool()->BitsPerPixel(); }
- virtual void Update();
-
- void SetVideoDeintMethod(std::string method);
- const char *GetStateName() {
- static const char *names[] = { "MMALStateNone", "MMALStateHWDec", "MMALStateFFDec", "MMALStateDeint", "MMALStateBypass", };
- if ((size_t)m_state < vcos_countof(names))
- return names[(size_t)m_state];
- else
- return "invalid";
- }
-protected:
-};
-
-
-class CMMALRenderer : public CBaseRenderer, public CThread, public IRunnable
-{
-public:
- CMMALRenderer();
- ~CMMALRenderer();
-
- void Process();
- virtual void Update();
-
- bool RenderCapture(CRenderCapture* capture);
-
- // Player functions
- virtual bool Configure(const VideoPicture &picture, float fps, unsigned int orientation) override;
- virtual void ReleaseBuffer(int idx) override;
- virtual void UnInit();
- virtual bool Flush(bool saveBuffers) override;
- virtual bool IsConfigured() override { return m_bConfigured; }
- virtual void AddVideoPicture(const VideoPicture& pic, int index) override;
- virtual bool IsPictureHW(const VideoPicture &picture) override { return false; };
- virtual CRenderInfo GetRenderInfo() override;
-
- virtual bool SupportsMultiPassRendering() override { return false; };
- virtual bool Supports(ERENDERFEATURE feature) override;
- virtual bool Supports(ESCALINGMETHOD method) override;
-
- virtual void RenderUpdate(int index, int index2, bool clear, unsigned int flags, unsigned int alpha) override;
-
- virtual void SetVideoRect(const CRect& SrcRect, const CRect& DestRect);
- virtual bool IsGuiLayer() override { return false; }
- virtual bool ConfigChanged(const VideoPicture &picture) override { return false; }
-
- void vout_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
- void deint_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
- void deint_output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
-
- static CBaseRenderer* Create(CVideoBuffer *buffer);
- static bool Register();
-
-protected:
- CMMALBuffer *m_buffers[NUM_BUFFERS];
- bool m_bConfigured;
- unsigned int m_extended_format;
- int m_neededBuffers;
-
- CRect m_cachedSourceRect;
- CRect m_cachedDestRect;
- CRect m_src_rect;
- CRect m_dst_rect;
- RENDER_STEREO_MODE m_video_stereo_mode;
- RENDER_STEREO_MODE m_display_stereo_mode;
- bool m_StereoInvert;
- bool m_isPi1;
-
- CCriticalSection m_sharedSection;
- MMAL_COMPONENT_T *m_vout;
- MMAL_PORT_T *m_vout_input;
- MMAL_QUEUE_T *m_queue_render;
- MMAL_QUEUE_T *m_queue_process;
- CThread m_processThread;
- MMAL_BUFFER_HEADER_T m_quitpacket;
- double m_error;
- double m_lastPts;
- double m_frameInterval;
- double m_frameIntervalDiff;
- uint32_t m_vout_width, m_vout_height, m_vout_aligned_width, m_vout_aligned_height;
- // deinterlace
- MMAL_COMPONENT_T *m_deint;
- MMAL_PORT_T *m_deint_input;
- MMAL_PORT_T *m_deint_output;
- std::shared_ptr<CMMALPool> m_deint_output_pool;
- MMAL_INTERLACETYPE_T m_interlace_mode;
- EINTERLACEMETHOD m_interlace_method;
- uint32_t m_deint_width, m_deint_height, m_deint_aligned_width, m_deint_aligned_height;
- MMAL_FOURCC_T m_deinterlace_out_encoding;
- void DestroyDeinterlace();
- bool CheckConfigurationDeint(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding, EINTERLACEMETHOD interlace_method, int bitsPerPixel);
-
- bool CheckConfigurationVout(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding);
- uint32_t m_vsync_count;
- void ReleaseBuffers();
- void UnInitMMAL();
- void UpdateFramerateStats(double pts);
- virtual void Run() override;
-};
-
-};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
index 735361946f..681323f8bc 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
@@ -35,14 +35,45 @@ CRendererDRMPRIME::~CRendererDRMPRIME()
CBaseRenderer* CRendererDRMPRIME::Create(CVideoBuffer* buffer)
{
- if (buffer && dynamic_cast<CVideoBufferDRMPRIME*>(buffer) &&
- CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
- SETTING_VIDEOPLAYER_USEPRIMERENDERER) == 0)
+ if (buffer && CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
+ SETTING_VIDEOPLAYER_USEPRIMERENDERER) == 0)
{
- CWinSystemGbm* winSystem = dynamic_cast<CWinSystemGbm*>(CServiceBroker::GetWinSystem());
- if (winSystem && winSystem->GetDrm()->GetVideoPlane()->plane &&
- std::dynamic_pointer_cast<CDRMAtomic>(winSystem->GetDrm()))
- return new CRendererDRMPRIME();
+ auto buf = dynamic_cast<CVideoBufferDRMPRIME*>(buffer);
+ if (!buf)
+ return nullptr;
+
+ auto winSystem = static_cast<CWinSystemGbm*>(CServiceBroker::GetWinSystem());
+ if (!winSystem)
+ return nullptr;
+
+ auto drm = std::static_pointer_cast<CDRMAtomic>(winSystem->GetDrm());
+ if (!drm)
+ return nullptr;
+
+ if (!buf->AcquireDescriptor())
+ return nullptr;
+
+ AVDRMFrameDescriptor* desc = buf->GetDescriptor();
+ if (!desc)
+ {
+ buf->ReleaseDescriptor();
+ return nullptr;
+ }
+
+ AVDRMLayerDescriptor* layer = &desc->layers[0];
+ uint32_t format = layer->format;
+ uint64_t modifier = desc->objects[0].format_modifier;
+
+ buf->ReleaseDescriptor();
+
+ auto plane = drm->GetVideoPlane();
+ if (!plane)
+ return nullptr;
+
+ if (!plane->SupportsFormatAndModifier(format, modifier))
+ return nullptr;
+
+ return new CRendererDRMPRIME();
}
return nullptr;
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
index 5002ef742c..3b7c9cd378 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
@@ -17,9 +17,9 @@
#include "utils/EGLFence.h"
#include "utils/GLUtils.h"
#include "utils/log.h"
-#include "windowing/gbm/WinSystemGbmEGLContext.h"
+#include "windowing/WinSystem.h"
+#include "windowing/linux/WinSystemEGL.h"
-using namespace KODI::WINDOWING::GBM;
using namespace KODI::UTILS::EGL;
CRendererDRMPRIMEGLES::~CRendererDRMPRIMEGLES()
@@ -44,11 +44,6 @@ bool CRendererDRMPRIMEGLES::Configure(const VideoPicture& picture,
float fps,
unsigned int orientation)
{
- CWinSystemGbmEGLContext* winSystem =
- dynamic_cast<CWinSystemGbmEGLContext*>(CServiceBroker::GetWinSystem());
- if (!winSystem)
- return false;
-
m_format = picture.videoBuffer->GetFormat();
m_sourceWidth = picture.iWidth;
m_sourceHeight = picture.iHeight;
@@ -66,7 +61,18 @@ bool CRendererDRMPRIMEGLES::Configure(const VideoPicture& picture,
Flush(false);
- EGLDisplay eglDisplay = winSystem->GetEGLDisplay();
+ auto winSystem = CServiceBroker::GetWinSystem();
+
+ if (!winSystem)
+ return false;
+
+ auto winSystemEGL = dynamic_cast<KODI::WINDOWING::LINUX::CWinSystemEGL*>(winSystem);
+
+ if (!winSystemEGL)
+ return false;
+
+ EGLDisplay eglDisplay = winSystemEGL->GetEGLDisplay();
+
for (auto&& buf : m_buffers)
{
if (!buf.fence)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
index 98086409da..8a8de74551 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
@@ -244,7 +244,7 @@ bool CLinuxRendererGL::Configure(const VideoPicture &picture, float fps, unsigne
// load 3DLUT
if (m_ColorManager->IsEnabled())
{
- if (!m_ColorManager->CheckConfiguration(m_cmsToken, m_iFlags))
+ if (!m_ColorManager->CheckConfiguration(m_cmsToken, m_srcPrimaries))
{
CLog::Log(LOGDEBUG, "CMS configuration changed, reload LUT");
if (!LoadCLUT())
@@ -674,7 +674,7 @@ void CLinuxRendererGL::UpdateVideoFilter()
(m_pixelRatio > 1.001f || m_pixelRatio < 0.999f);
bool nonLinStretchChanged = false;
bool cmsChanged = (m_cmsOn != m_ColorManager->IsEnabled()) ||
- (m_cmsOn && !m_ColorManager->CheckConfiguration(m_cmsToken, m_iFlags));
+ (m_cmsOn && !m_ColorManager->CheckConfiguration(m_cmsToken, m_srcPrimaries));
if (m_nonLinStretchGui != CDisplaySettings::GetInstance().IsNonLinearStretched() || pixelRatioChanged)
{
m_nonLinStretchGui = CDisplaySettings::GetInstance().IsNonLinearStretched();
@@ -714,7 +714,7 @@ void CLinuxRendererGL::UpdateVideoFilter()
{
if (m_ColorManager->IsEnabled())
{
- if (!m_ColorManager->CheckConfiguration(m_cmsToken, m_iFlags))
+ if (!m_ColorManager->CheckConfiguration(m_cmsToken, m_srcPrimaries))
{
CLog::Log(LOGDEBUG, "CMS configuration changed, reload LUT");
LoadCLUT();
@@ -2670,7 +2670,8 @@ bool CLinuxRendererGL::LoadCLUT()
m_CLUT = static_cast<uint16_t*>(malloc(dataSize));
// load 3DLUT
- if ( !m_ColorManager->GetVideo3dLut(m_iFlags, &m_cmsToken, CMS_DATA_FMT_RGB, m_CLUTsize, m_CLUT) )
+ if (!m_ColorManager->GetVideo3dLut(m_srcPrimaries, &m_cmsToken, CMS_DATA_FMT_RGB, m_CLUTsize,
+ m_CLUT))
{
free(m_CLUT);
CLog::Log(LOGERROR, "Error loading the LUT");
@@ -2681,7 +2682,7 @@ bool CLinuxRendererGL::LoadCLUT()
CLog::Log(LOGDEBUG, "LinuxRendererGL: creating 3DLUT");
glGenTextures(1, &m_tCLUTTex);
glActiveTexture(GL_TEXTURE4);
- if ( m_tCLUTTex <= 0 )
+ if (m_tCLUTTex <= 0)
{
CLog::Log(LOGERROR, "Error creating 3DLUT texture");
return false;
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp
index 395bd85bc9..7baa6f1f83 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp
@@ -49,45 +49,7 @@ bool CRenderCaptureBase::UseOcclusionQuery()
return true;
}
-#if defined(TARGET_RASPBERRY_PI)
-
-CRenderCaptureDispmanX::CRenderCaptureDispmanX()
-{
- m_pixels = nullptr;
-}
-
-CRenderCaptureDispmanX::~CRenderCaptureDispmanX()
-{
- delete[] m_pixels;
-}
-
-int CRenderCaptureDispmanX::GetCaptureFormat()
-{
- return CAPTUREFORMAT_BGRA;
-}
-
-void CRenderCaptureDispmanX::BeginRender()
-{
-}
-
-void CRenderCaptureDispmanX::EndRender()
-{
- delete[] m_pixels;
- m_pixels = g_RBP.CaptureDisplay(m_width, m_height, NULL, true);
-
- SetState(CAPTURESTATE_DONE);
-}
-
-void* CRenderCaptureDispmanX::GetRenderBuffer()
-{
- return m_pixels;
-}
-
-void CRenderCaptureDispmanX::ReadOut()
-{
-}
-
-#elif defined(HAS_GL) || defined(HAS_GLES)
+#if defined(HAS_GL) || defined(HAS_GLES)
CRenderCaptureGL::CRenderCaptureGL()
{
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h
index d371536116..cc1a969fe0 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h
@@ -100,33 +100,7 @@ class CRenderCaptureBase
bool m_asyncChecked;
};
-#if defined(TARGET_RASPBERRY_PI)
-#include "platform/linux/RBP.h"
-
-class CRenderCaptureDispmanX : public CRenderCaptureBase
-{
- public:
- CRenderCaptureDispmanX();
- ~CRenderCaptureDispmanX();
-
- int GetCaptureFormat();
-
- void BeginRender();
- void EndRender();
- void ReadOut();
-
- void* GetRenderBuffer();
-};
-
-//used instead of typedef CRenderCaptureGL CRenderCapture
-//since C++ doesn't allow you to forward declare a typedef
-class CRenderCapture : public CRenderCaptureDispmanX
-{
- public:
- CRenderCapture() {};
-};
-
-#elif defined(HAS_GL) || defined(HAS_GLES)
+#if defined(HAS_GL) || defined(HAS_GLES)
#include "system_gl.h"
class CRenderCaptureGL : public CRenderCaptureBase
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h b/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h
index b366b5d99e..ba5b21c112 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h
@@ -29,7 +29,6 @@ class CRenderCapture;
struct VideoPicture;
class CWinRenderer;
-class CMMALRenderer;
class CLinuxRenderer;
class CLinuxRendererGL;
class CLinuxRendererGLES;
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp
index 8ef572e6e0..38913111e7 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp
@@ -350,19 +350,20 @@ bool CRendererBase::CreateIntermediateTarget(unsigned width, unsigned height, bo
return true;
}
-void CRendererBase::OnCMSConfigChanged(unsigned flags)
+void CRendererBase::OnCMSConfigChanged(AVColorPrimaries srcPrimaries)
{
m_lutSize = 0;
m_clutLoaded = false;
- auto loadLutTask = Concurrency::create_task([this, flags] {
+ auto loadLutTask = Concurrency::create_task([this, srcPrimaries] {
// load 3DLUT data
int lutSize, dataSize;
if (!CColorManager::Get3dLutSize(CMS_DATA_FMT_RGBA, &lutSize, &dataSize))
return 0;
const auto lutData = static_cast<uint16_t*>(KODI::MEMORY::AlignedMalloc(dataSize, 16));
- bool success = m_colorManager->GetVideo3dLut(flags, &m_cmsToken, CMS_DATA_FMT_RGBA, lutSize, lutData);
+ bool success = m_colorManager->GetVideo3dLut(srcPrimaries, &m_cmsToken, CMS_DATA_FMT_RGBA,
+ lutSize, lutData);
if (success)
{
success = COutputShader::CreateLUTView(lutSize, lutData, false, m_pLUTView.ReleaseAndGetAddressOf());
@@ -442,7 +443,7 @@ void CRendererBase::CheckVideoParameters()
OnOutputReset();
}
- const unsigned color_primaries = GetFlagsColorPrimaries(buf->primaries);
+ const AVColorPrimaries color_primaries = static_cast<AVColorPrimaries>(buf->primaries);
if (m_cmsOn && !m_colorManager->CheckConfiguration(m_cmsToken, color_primaries))
{
OnCMSConfigChanged(color_primaries);
@@ -518,7 +519,13 @@ void CRendererBase::ProcessHDR(CRenderBuffer* rb)
}
if (!DX::Windowing()->IsHDROutput())
+ {
+ if (m_lastHdr10.RedPrimary[0] != 0)
+ m_lastHdr10 = {};
+ if (m_HdrType != HDR_TYPE::HDR_NONE_SDR)
+ m_HdrType = HDR_TYPE::HDR_NONE_SDR;
return;
+ }
// HDR10
if (rb->color_transfer == AVCOL_TRC_SMPTE2084 && rb->primaries == AVCOL_PRI_BT2020)
@@ -579,6 +586,7 @@ void CRendererBase::ProcessHDR(CRenderBuffer* rb)
DX::Windowing()->SetHdrColorSpace(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
m_HdrType = HDR_TYPE::HDR_NONE_SDR;
m_iCntMetaData = 0;
+ m_lastHdr10 = {};
if (m_AutoSwitchHDR)
DX::Windowing()->ToggleHDR(); // Toggle display HDR OFF
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h
index 999e6b7d48..69e02edf5c 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h
@@ -137,7 +137,7 @@ protected:
explicit CRendererBase(CVideoSettings& videoSettings);
bool CreateIntermediateTarget(unsigned int width, unsigned int height, bool dynamic = false);
- void OnCMSConfigChanged(unsigned flags);
+ void OnCMSConfigChanged(AVColorPrimaries srcPrimaries);
void ReorderDrawPoints(const CRect& destRect, CPoint(&rotatedPoints)[4]) const;
bool CreateRenderBuffer(int index);
void DeleteRenderBuffer(int index);
diff --git a/xbmc/cores/VideoSettings.h b/xbmc/cores/VideoSettings.h
index bedeb37dcd..bd9ac62f8e 100644
--- a/xbmc/cores/VideoSettings.h
+++ b/xbmc/cores/VideoSettings.h
@@ -30,10 +30,6 @@ enum EINTERLACEMETHOD
VS_INTERLACEMETHOD_VAAPI_BOB = 22,
VS_INTERLACEMETHOD_VAAPI_MADI = 23,
VS_INTERLACEMETHOD_VAAPI_MACI = 24,
- VS_INTERLACEMETHOD_MMAL_ADVANCED = 25,
- VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF = 26,
- VS_INTERLACEMETHOD_MMAL_BOB = 27,
- VS_INTERLACEMETHOD_MMAL_BOB_HALF = 28,
VS_INTERLACEMETHOD_DXVA_AUTO = 32,
VS_INTERLACEMETHOD_MAX // do not use and keep as last enum value.
};
diff --git a/xbmc/cores/omxplayer/CMakeLists.txt b/xbmc/cores/omxplayer/CMakeLists.txt
deleted file mode 100644
index 038274bf71..0000000000
--- a/xbmc/cores/omxplayer/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-set(SOURCES OMXImage.cpp)
-
-set(HEADERS OMXImage.h)
-
-core_add_library(omxplayer)
-target_compile_definitions(${CORE_LIBRARY} PRIVATE -D__STDC_FORMAT_MACROS)
diff --git a/xbmc/cores/omxplayer/OMXImage.cpp b/xbmc/cores/omxplayer/OMXImage.cpp
deleted file mode 100644
index 1c1a258236..0000000000
--- a/xbmc/cores/omxplayer/OMXImage.cpp
+++ /dev/null
@@ -1,2340 +0,0 @@
-/*
- * Copyright (C) 2010-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "OMXImage.h"
-
-#include "Application.h"
-#include "ServiceBroker.h"
-#include "URL.h"
-#include "settings/AdvancedSettings.h"
-#include "settings/DisplaySettings.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "utils/URIUtils.h"
-#include "utils/log.h"
-#include "windowing/GraphicContext.h"
-#include "windowing/WinSystem.h"
-#include "windowing/rpi/WinSystemRpiGLESContext.h"
-
-#include "platform/linux/RBP.h"
-
-#include <algorithm>
-#include <cassert>
-#include <inttypes.h>
-
-#include <sys/time.h>
-
-#ifdef _DEBUG
-#define CheckError() { GLint result = eglGetError(); if (result != EGL_SUCCESS) CLog::Log(LOGERROR, "EGL error in %s: %x", __FUNCTION__, result); }
-#else
-#define CheckError()
-#endif
-
-#define EXIF_TAG_ORIENTATION 0x0112
-
-
-// A helper for restricting threads calling GPU functions to limit memory use
-// Experimentally, 3 outstanding operations is optimal
-static XbmcThreads::ConditionVariable g_count_cond;
-static CCriticalSection g_count_lock;
-static int g_count_val;
-
-static void limit_calls_enter()
-{
- CSingleLock lock(g_count_lock);
- while (g_count_val >= 3)
- g_count_cond.wait(lock);
- g_count_val++;
-}
-
-static void limit_calls_leave()
-{
- CSingleLock lock(g_count_lock);
- g_count_val--;
- g_count_cond.notifyAll();
-}
-
-
-#ifdef CLASSNAME
-#undef CLASSNAME
-#endif
-#define CLASSNAME "COMXImage"
-
-using namespace XFILE;
-
-COMXImage::COMXImage()
-: CThread("CRBPWorker")
-{
- m_egl_context = EGL_NO_CONTEXT;
-}
-
-COMXImage::~COMXImage()
-{
- Deinitialize();
-}
-
-void COMXImage::Initialize()
-{
- Create();
-}
-
-void COMXImage::Deinitialize()
-{
- // wake up thread so it can quit
- {
- CSingleLock lock(m_texqueue_lock);
- m_bStop = true;
- m_texqueue_cond.notifyAll();
- }
- if (IsRunning())
- StopThread();
-}
-
-bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
- unsigned int format, unsigned int pitch, const std::string& destFile)
-{
- COMXImageEnc omxImageEnc;
- bool ret = omxImageEnc.CreateThumbnailFromSurface(buffer, width, height, format, pitch, destFile);
- if (!ret)
- CLog::Log(LOGINFO, "%s: unable to create thumbnail %s %dx%d", __func__, destFile.c_str(), width,
- height);
- return ret;
-}
-
-COMXImageFile *COMXImage::LoadJpeg(const std::string& texturePath)
-{
- COMXImageFile *file = new COMXImageFile();
- if (!file->ReadFile(texturePath))
- {
- CLog::Log(LOGINFO, "%s: unable to load %s", __func__, CURL::GetRedacted(texturePath).c_str());
- delete file;
- file = NULL;
- }
- return file;
-}
-
-void COMXImage::CloseJpeg(COMXImageFile *file)
-{
- delete file;
-}
-
-bool COMXImage::DecodeJpeg(COMXImageFile *file, unsigned int width, unsigned int height, unsigned int stride, void *pixels)
-{
- bool ret = false;
- COMXImageDec omx_image;
- if (omx_image.Decode(file->GetImageBuffer(), file->GetImageSize(), width, height, stride, pixels))
- {
- assert(width == omx_image.GetDecodedWidth());
- assert(height == omx_image.GetDecodedHeight());
- assert(stride == omx_image.GetDecodedStride());
- ret = true;
- }
- else
- CLog::Log(LOGINFO, "%s: unable to decode %s %dx%d", __func__, file->GetFilename(), width,
- height);
- omx_image.Close();
- return ret;
-}
-
-bool COMXImage::ClampLimits(unsigned int &width, unsigned int &height, unsigned int m_width, unsigned int m_height, bool transposed)
-{
- RESOLUTION_INFO& res_info = CDisplaySettings::GetInstance().GetResolutionInfo(CServiceBroker::GetWinSystem()->GetGfxContext().GetVideoResolution());
- unsigned int max_width = width;
- unsigned int max_height = height;
- const unsigned int gui_width = transposed ? res_info.iHeight:res_info.iWidth;
- const unsigned int gui_height = transposed ? res_info.iWidth:res_info.iHeight;
- const float aspect = (float)m_width / m_height;
- bool clamped = false;
-
- if (max_width == 0 || max_height == 0)
- {
- const std::shared_ptr<CAdvancedSettings> advancedSettings = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings();
-
- max_height = advancedSettings->m_imageRes;
-
- if (advancedSettings->m_fanartRes > advancedSettings->m_imageRes)
- { // 16x9 images larger than the fanart res use that rather than the image res
- if (fabsf(aspect / (16.0f/9.0f) - 1.0f) <= 0.01f && m_height >= advancedSettings->m_fanartRes)
- {
- max_height = advancedSettings->m_fanartRes;
- }
- }
- max_width = max_height * 16/9;
- }
-
- if (gui_width)
- max_width = std::min(max_width, gui_width);
- if (gui_height)
- max_height = std::min(max_height, gui_height);
-
- max_width = std::min(max_width, 2048U);
- max_height = std::min(max_height, 2048U);
-
- width = m_width;
- height = m_height;
- if (width > max_width || height > max_height)
- {
- if ((unsigned int)(max_width / aspect + 0.5f) > max_height)
- max_width = (unsigned int)(max_height * aspect + 0.5f);
- else
- max_height = (unsigned int)(max_width / aspect + 0.5f);
- width = max_width;
- height = max_height;
- clamped = true;
- }
-
- return clamped;
-}
-
-bool COMXImage::CreateThumb(const std::string& srcFile, unsigned int maxHeight, unsigned int maxWidth, std::string &additional_info, const std::string& destFile)
-{
- bool okay = false;
- COMXImageFile file;
- COMXImageReEnc reenc;
- void *pDestBuffer;
- unsigned int nDestSize;
- int orientation = additional_info == "flipped" ? 1:0;
- if (URIUtils::HasExtension(srcFile, ".jpg|.tbn") && file.ReadFile(srcFile, orientation) && reenc.ReEncode(file, maxWidth, maxHeight, pDestBuffer, nDestSize))
- {
- XFILE::CFile outfile;
- if (outfile.OpenForWrite(destFile, true))
- {
- outfile.Write(pDestBuffer, nDestSize);
- outfile.Close();
- okay = true;
- }
- else
- CLog::Log(LOGERROR, "%s: can't open output file: %s", __func__, destFile.c_str());
- }
- return okay;
-}
-
-bool COMXImage::SendMessage(bool (*callback)(EGLDisplay egl_display, EGLContext egl_context, void *cookie), void *cookie)
-{
- // we can only call gl functions from the application thread or texture thread
- if ( g_application.IsCurrentThread() )
- {
- CWinSystemRpiGLESContext *winsystem = static_cast<CWinSystemRpiGLESContext *>(CServiceBroker::GetWinSystem());
- return callback(winsystem->GetEGLDisplay(), GetEGLContext(), cookie);
- }
- struct callbackinfo mess;
- mess.callback = callback;
- mess.cookie = cookie;
- mess.result = false;
- mess.sync.Reset();
- {
- CSingleLock lock(m_texqueue_lock);
- m_texqueue.push(&mess);
- m_texqueue_cond.notifyAll();
- }
- // wait for function to have finished (in texture thread)
- mess.sync.Wait();
- // need to ensure texture thread has returned from mess.sync.Set() before we exit and free tex
- CSingleLock lock(m_texqueue_lock);
- return mess.result;
-}
-
-
-static bool AllocTextureCallback(EGLDisplay egl_display, EGLContext egl_context, void *cookie)
-{
- struct COMXImage::textureinfo *tex = static_cast<struct COMXImage::textureinfo *>(cookie);
- COMXImage *img = static_cast<COMXImage*>(tex->parent);
- return img->AllocTextureInternal(egl_display, egl_context, tex);
-}
-
-bool COMXImage::AllocTextureInternal(EGLDisplay egl_display, EGLContext egl_context, struct textureinfo *tex)
-{
- glGenTextures(1, (GLuint*) &tex->texture);
- glBindTexture(GL_TEXTURE_2D, tex->texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- GLenum type = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool("videoscreen.textures32") ? GL_UNSIGNED_BYTE:GL_UNSIGNED_SHORT_5_6_5;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex->width, tex->height, 0, GL_RGB, type, 0);
- tex->egl_image = eglCreateImageKHR(egl_display, egl_context, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)tex->texture, NULL);
- if (!tex->egl_image)
- CLog::Log(LOGDEBUG, "%s: eglCreateImageKHR failed to allocate", __func__);
- CheckError();
- return true;
-}
-
-void COMXImage::GetTexture(void *userdata, GLuint *texture)
-{
- struct textureinfo *tex = static_cast<struct textureinfo *>(userdata);
- *texture = tex->texture;
-}
-
-static bool DestroyTextureCallback(EGLDisplay egl_display, EGLContext egl_context, void *cookie)
-{
- struct COMXImage::textureinfo *tex = static_cast<struct COMXImage::textureinfo *>(cookie);
- COMXImage *img = static_cast<COMXImage*>(tex->parent);
- return img->DestroyTextureInternal(egl_display, egl_context, tex);
-}
-
-void COMXImage::DestroyTexture(void *userdata)
-{
- SendMessage(DestroyTextureCallback, userdata);
-}
-
-bool COMXImage::DestroyTextureInternal(EGLDisplay egl_display, EGLContext egl_context, struct textureinfo *tex)
-{
- bool s = true;
- if (tex->egl_image)
- {
- s = eglDestroyImageKHR(egl_display, tex->egl_image);
- if (!s)
- CLog::Log(LOGINFO, "%s: failed to destroy texture", __func__);
- }
- if (tex->texture)
- glDeleteTextures(1, (GLuint*) &tex->texture);
- return s;
-}
-
-bool COMXImage::DecodeJpegToTexture(COMXImageFile *file, unsigned int width, unsigned int height, void **userdata)
-{
- bool ret = false;
- COMXTexture omx_image;
-
- struct textureinfo *tex = new struct textureinfo;
- if (!tex)
- return NULL;
-
- tex->parent = (void *)this;
- tex->width = width;
- tex->height = height;
- tex->texture = 0;
- tex->egl_image = NULL;
-
- SendMessage(AllocTextureCallback, tex);
-
- if (tex->egl_image && tex->texture && omx_image.Decode(file->GetImageBuffer(), file->GetImageSize(), width, height, tex->egl_image))
- {
- ret = true;
- *userdata = tex;
- CLog::Log(LOGDEBUG, "%s: decoded %s %dx%d", __func__, file->GetFilename(), width, height);
- }
- else
- {
- CLog::Log(LOGINFO, "%s: unable to decode to texture %s %dx%d", __func__, file->GetFilename(),
- width, height);
- DestroyTexture(tex);
- }
- return ret;
-}
-
-EGLContext COMXImage::GetEGLContext()
-{
- CSingleLock lock(m_texqueue_lock);
- CWinSystemRpiGLESContext *winsystem = static_cast<CWinSystemRpiGLESContext *>(CServiceBroker::GetWinSystem());
- if (g_application.IsCurrentThread())
- return winsystem->GetEGLContext();
- if (m_egl_context == EGL_NO_CONTEXT)
- CreateContext();
- return m_egl_context;
-}
-
-static bool ChooseConfig(EGLDisplay display, const EGLint *configAttrs, EGLConfig *config)
-{
- EGLBoolean eglStatus = true;
- EGLint configCount = 0;
- EGLConfig* configList = NULL;
- // Find out how many configurations suit our needs
- eglStatus = eglChooseConfig(display, configAttrs, NULL, 0, &configCount);
- CheckError();
-
- if (!eglStatus || !configCount)
- {
- CLog::Log(LOGERROR, "EGL failed to return any matching configurations: %i", configCount);
- return false;
- }
-
- // Allocate room for the list of matching configurations
- configList = (EGLConfig*)malloc(configCount * sizeof(EGLConfig));
- if (!configList)
- {
- CLog::Log(LOGERROR, "EGL failure obtaining configuration list");
- return false;
- }
-
- // Obtain the configuration list from EGL
- eglStatus = eglChooseConfig(display, configAttrs, configList, configCount, &configCount);
- CheckError();
- if (!eglStatus || !configCount)
- {
- CLog::Log(LOGERROR, "EGL failed to populate configuration list: %d", eglStatus);
- return false;
- }
-
- // Select an EGL configuration that matches the native window
- *config = configList[0];
-
- free(configList);
- return true;
-}
-
-void COMXImage::CreateContext()
-{
- EGLConfig egl_config;
- CWinSystemRpiGLESContext *winsystem = static_cast<CWinSystemRpiGLESContext *>(CServiceBroker::GetWinSystem());
- EGLDisplay egl_display = winsystem->GetEGLDisplay();
-
- eglInitialize(egl_display, NULL, NULL);
- CheckError();
- eglBindAPI(EGL_OPENGL_ES_API);
- CheckError();
- static const EGLint contextAttrs [] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
- static const EGLint configAttrs [] = {
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_DEPTH_SIZE, 16,
- EGL_STENCIL_SIZE, 0,
- EGL_SAMPLE_BUFFERS, 0,
- EGL_SAMPLES, 0,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
- bool s = ChooseConfig(egl_display, configAttrs, &egl_config);
- CheckError();
- if (!s)
- {
- CLog::Log(LOGERROR, "%s: Could not find a compatible configuration",__FUNCTION__);
- return;
- }
- m_egl_context = eglCreateContext(egl_display, egl_config, winsystem->GetEGLContext(), contextAttrs);
- CheckError();
- if (m_egl_context == EGL_NO_CONTEXT)
- {
- CLog::Log(LOGERROR, "%s: Could not create a context",__FUNCTION__);
- return;
- }
- EGLSurface egl_surface = eglCreatePbufferSurface(egl_display, egl_config, NULL);
- CheckError();
- if (egl_surface == EGL_NO_SURFACE)
- {
- CLog::Log(LOGERROR, "%s: Could not create a surface",__FUNCTION__);
- return;
- }
- s = eglMakeCurrent(egl_display, egl_surface, egl_surface, m_egl_context);
- CheckError();
- if (!s)
- {
- CLog::Log(LOGERROR, "%s: Could not make current",__FUNCTION__);
- return;
- }
-}
-
-void COMXImage::Process()
-{
- while(!m_bStop)
- {
- CSingleLock lock(m_texqueue_lock);
- if (m_texqueue.empty())
- {
- m_texqueue_cond.wait(lock);
- }
- else
- {
- struct callbackinfo *mess = m_texqueue.front();
- m_texqueue.pop();
- lock.Leave();
-
- CWinSystemRpiGLESContext *winsystem = static_cast<CWinSystemRpiGLESContext *>(CServiceBroker::GetWinSystem());
- mess->result = mess->callback(winsystem->GetEGLDisplay(), GetEGLContext(), mess->cookie);
- {
- CSingleLock lock(m_texqueue_lock);
- mess->sync.Set();
- }
- }
- }
-}
-
-void COMXImage::OnStartup()
-{
-}
-
-void COMXImage::OnExit()
-{
-}
-
-#ifdef CLASSNAME
-#undef CLASSNAME
-#endif
-#define CLASSNAME "COMXImageFile"
-
-COMXImageFile::COMXImageFile()
-{
- m_image_size = 0;
- m_image_buffer = NULL;
- m_orientation = 0;
- m_width = 0;
- m_height = 0;
-}
-
-COMXImageFile::~COMXImageFile()
-{
- if(m_image_buffer)
- free(m_image_buffer);
-}
-
-typedef enum { /* JPEG marker codes */
- M_SOF0 = 0xc0,
- M_SOF1 = 0xc1,
- M_SOF2 = 0xc2,
- M_SOF3 = 0xc3,
- M_SOF5 = 0xc5,
- M_SOF6 = 0xc6,
- M_SOF7 = 0xc7,
- M_JPG = 0xc8,
- M_SOF9 = 0xc9,
- M_SOF10 = 0xca,
- M_SOF11 = 0xcb,
- M_SOF13 = 0xcd,
- M_SOF14 = 0xce,
- M_SOF15 = 0xcf,
-
- M_DHT = 0xc4,
- M_DAC = 0xcc,
-
- M_RST0 = 0xd0,
- M_RST1 = 0xd1,
- M_RST2 = 0xd2,
- M_RST3 = 0xd3,
- M_RST4 = 0xd4,
- M_RST5 = 0xd5,
- M_RST6 = 0xd6,
- M_RST7 = 0xd7,
-
- M_SOI = 0xd8,
- M_EOI = 0xd9,
- M_SOS = 0xda,
- M_DQT = 0xdb,
- M_DNL = 0xdc,
- M_DRI = 0xdd,
- M_DHP = 0xde,
- M_EXP = 0xdf,
-
- M_APP0 = 0xe0,
- M_APP1 = 0xe1,
- M_APP2 = 0xe2,
- M_APP3 = 0xe3,
- M_APP4 = 0xe4,
- M_APP5 = 0xe5,
- M_APP6 = 0xe6,
- M_APP7 = 0xe7,
- M_APP8 = 0xe8,
- M_APP9 = 0xe9,
- M_APP10 = 0xea,
- M_APP11 = 0xeb,
- M_APP12 = 0xec,
- M_APP13 = 0xed,
- M_APP14 = 0xee,
- M_APP15 = 0xef,
- // extensions
- M_JPG0 = 0xf0,
- M_JPG1 = 0xf1,
- M_JPG2 = 0xf2,
- M_JPG3 = 0xf3,
- M_JPG4 = 0xf4,
- M_JPG5 = 0xf5,
- M_JPG6 = 0xf6,
- M_JPG7 = 0xf7,
- M_JPG8 = 0xf8,
- M_JPG9 = 0xf9,
- M_JPG10 = 0xfa,
- M_JPG11 = 0xfb,
- M_JPG12 = 0xfc,
- M_JPG13 = 0xfd,
- M_JPG14 = 0xfe,
- M_COM = 0xff,
-
- M_TEM = 0x01,
-} JPEG_MARKER;
-
-static uint8_t inline READ8(uint8_t * &p)
-{
- uint8_t r = p[0];
- p += 1;
- return r;
-}
-
-static uint16_t inline READ16(uint8_t * &p)
-{
- uint16_t r = (p[0] << 8) | p[1];
- p += 2;
- return r;
-}
-
-static uint32_t inline READ32(uint8_t * &p)
-{
- uint32_t r = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
- p += 4;
- return r;
-}
-
-static void inline SKIPN(uint8_t * &p, unsigned int n)
-{
- p += n;
-}
-
-OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height, int orientation)
-{
- OMX_IMAGE_CODINGTYPE eCompressionFormat = OMX_IMAGE_CodingMax;
- bool progressive = false;
- int components = 0;
- m_orientation = 0;
-
- if(!m_image_size)
- {
- CLog::Log(LOGERROR, "%s::%s %s m_image_size unexpected (%lu)", CLASSNAME, __func__,
- GetFilename(), m_image_size);
- return OMX_IMAGE_CodingMax;
- }
-
- uint8_t *p = m_image_buffer;
- uint8_t *q = m_image_buffer + m_image_size;
-
- /* JPEG Header */
- if(READ16(p) == 0xFFD8)
- {
- eCompressionFormat = OMX_IMAGE_CodingJPEG;
-
- READ8(p);
- unsigned char marker = READ8(p);
- unsigned short block_size = 0;
- bool nMarker = false;
-
- while(p < q && !progressive)
- {
- switch(marker)
- {
- case M_DQT:
- case M_DNL:
- case M_DHP:
- case M_EXP:
-
- case M_DHT:
-
- case M_SOF0:
- case M_SOF1:
- case M_SOF2:
- case M_SOF3:
-
- case M_SOF5:
- case M_SOF6:
- case M_SOF7:
-
- case M_JPG:
- case M_SOF9:
- case M_SOF10:
- case M_SOF11:
-
- case M_SOF13:
- case M_SOF14:
- case M_SOF15:
-
- case M_APP0:
- case M_APP1:
- case M_APP2:
- case M_APP3:
- case M_APP4:
- case M_APP5:
- case M_APP6:
- case M_APP7:
- case M_APP8:
- case M_APP9:
- case M_APP10:
- case M_APP11:
- case M_APP12:
- case M_APP13:
- case M_APP14:
- case M_APP15:
-
- case M_JPG0:
- case M_JPG1:
- case M_JPG2:
- case M_JPG3:
- case M_JPG4:
- case M_JPG5:
- case M_JPG6:
- case M_JPG7:
- case M_JPG8:
- case M_JPG9:
- case M_JPG10:
- case M_JPG11:
- case M_JPG12:
- case M_JPG13:
- case M_JPG14:
- case M_COM:
- block_size = READ16(p);
- nMarker = true;
- break;
-
- case M_SOS:
- default:
- nMarker = false;
- break;
- }
-
- if(!nMarker)
- {
- break;
- }
-
- if(marker >= M_SOF0 && marker <= M_SOF15 && marker != M_DHT && marker != M_DAC)
- {
- if(marker == M_SOF2 || marker == M_SOF6 || marker == M_SOF10 || marker == M_SOF14)
- {
- progressive = true;
- }
- int readBits = 2;
- SKIPN(p, 1);
- readBits ++;
- height = READ16(p);
- readBits += 2;
- width = READ16(p);
- readBits += 2;
- components = READ8(p);
- readBits += 1;
- SKIPN(p, 1 * (block_size - readBits));
- }
- else if(marker == M_APP1)
- {
- int readBits = 2;
-
- // Exif header
- if(READ32(p) == 0x45786966)
- {
- bool bMotorola = false;
- bool bError = false;
- SKIPN(p, 1 * 2);
- readBits += 2;
-
- char o1 = READ8(p);
- char o2 = READ8(p);
- readBits += 2;
-
- /* Discover byte order */
- if(o1 == 'M' && o2 == 'M')
- bMotorola = true;
- else if(o1 == 'I' && o2 == 'I')
- bMotorola = false;
- else
- bError = true;
-
- SKIPN(p, 1 * 2);
- readBits += 2;
-
- if(!bError)
- {
- unsigned int offset, a, b, numberOfTags, tagNumber;
-
- // Get first IFD offset (offset to IFD0)
- if(bMotorola)
- {
- SKIPN(p, 1 * 2);
- readBits += 2;
-
- a = READ8(p);
- b = READ8(p);
- readBits += 2;
- offset = (a << 8) + b;
- }
- else
- {
- a = READ8(p);
- b = READ8(p);
- readBits += 2;
- offset = (b << 8) + a;
-
- SKIPN(p, 1 * 2);
- readBits += 2;
- }
-
- offset -= 8;
- if(offset > 0)
- {
- SKIPN(p, 1 * offset);
- readBits += offset;
- }
-
- // Get the number of directory entries contained in this IFD
- if(bMotorola)
- {
- a = READ8(p);
- b = READ8(p);
- numberOfTags = (a << 8) + b;
- }
- else
- {
- a = READ8(p);
- b = READ8(p);
- numberOfTags = (b << 8) + a;
- }
- readBits += 2;
-
- while(numberOfTags && p < q)
- {
- // Get Tag number
- if(bMotorola)
- {
- a = READ8(p);
- b = READ8(p);
- tagNumber = (a << 8) + b;
- readBits += 2;
- }
- else
- {
- a = READ8(p);
- b = READ8(p);
- tagNumber = (b << 8) + a;
- readBits += 2;
- }
-
- //found orientation tag
- if(tagNumber == EXIF_TAG_ORIENTATION)
- {
- if(bMotorola)
- {
- SKIPN(p, 1 * 7);
- readBits += 7;
- m_orientation = READ8(p)-1;
- readBits += 1;
- SKIPN(p, 1 * 2);
- readBits += 2;
- }
- else
- {
- SKIPN(p, 1 * 6);
- readBits += 6;
- m_orientation = READ8(p)-1;
- readBits += 1;
- SKIPN(p, 1 * 3);
- readBits += 3;
- }
- break;
- }
- else
- {
- SKIPN(p, 1 * 10);
- readBits += 10;
- }
- numberOfTags--;
- }
- }
- }
- readBits += 4;
- SKIPN(p, 1 * (block_size - readBits));
- }
- else
- {
- SKIPN(p, 1 * (block_size - 2));
- }
-
- READ8(p);
- marker = READ8(p);
-
- }
- }
- else
- CLog::Log(LOGERROR, "%s::%s error unsupported image format", CLASSNAME, __func__);
-
- // apply input orientation
- m_orientation = m_orientation ^ orientation;
- if(m_orientation < 0 || m_orientation >= 8)
- m_orientation = 0;
-
- if(progressive)
- {
- CLog::Log(LOGWARNING, "%s::%s progressive images not supported by decoder", CLASSNAME,
- __func__);
- eCompressionFormat = OMX_IMAGE_CodingMax;
- }
-
- if(components > 3)
- {
- CLog::Log(LOGWARNING, "%s::%s Only YUV images are supported by decoder", CLASSNAME, __func__);
- eCompressionFormat = OMX_IMAGE_CodingMax;
- }
-
- return eCompressionFormat;
-}
-
-
-bool COMXImageFile::ReadFile(const std::string& inputFile, int orientation)
-{
- XFILE::CFile m_pFile;
- m_filename = CURL::GetRedacted(inputFile);
- if(!m_pFile.Open(inputFile, 0))
- {
- CLog::Log(LOGERROR, "%s::%s %s not found", CLASSNAME, __func__, GetFilename());
- return false;
- }
-
- if(m_image_buffer)
- free(m_image_buffer);
- m_image_buffer = NULL;
-
- m_image_size = m_pFile.GetLength();
-
- if(!m_image_size)
- {
- CLog::Log(LOGERROR, "%s::%s %s m_image_size zero", CLASSNAME, __func__, GetFilename());
- return false;
- }
- m_image_buffer = (uint8_t *)malloc(m_image_size);
- if(!m_image_buffer)
- {
- CLog::Log(LOGERROR, "%s::%s %s m_image_buffer null (%lu)", CLASSNAME, __func__, GetFilename(),
- m_image_size);
- return false;
- }
-
- m_pFile.Read(m_image_buffer, m_image_size);
- m_pFile.Close();
-
- OMX_IMAGE_CODINGTYPE eCompressionFormat = GetCodingType(m_width, m_height, orientation);
- if(eCompressionFormat != OMX_IMAGE_CodingJPEG || m_width < 1 || m_height < 1)
- {
- CLog::Log(LOGDEBUG, "%s::%s %s GetCodingType=0x%x (%dx%d)", CLASSNAME, __func__, GetFilename(),
- eCompressionFormat, m_width, m_height);
- return false;
- }
-
- return true;
-}
-
-#ifdef CLASSNAME
-#undef CLASSNAME
-#endif
-#define CLASSNAME "COMXImageDec"
-
-COMXImageDec::COMXImageDec()
-{
- limit_calls_enter();
- m_decoded_buffer = NULL;
- OMX_INIT_STRUCTURE(m_decoded_format);
- m_success = false;
-}
-
-COMXImageDec::~COMXImageDec()
-{
- Close();
-
- OMX_INIT_STRUCTURE(m_decoded_format);
- m_decoded_buffer = NULL;
- limit_calls_leave();
-}
-
-void COMXImageDec::Close()
-{
- CSingleLock lock(m_OMXSection);
-
- if (!m_success)
- {
- if(m_omx_decoder.IsInitialized())
- {
- m_omx_decoder.SetStateForComponent(OMX_StateIdle);
- m_omx_decoder.FlushInput();
- m_omx_decoder.FreeInputBuffers();
- }
- if(m_omx_resize.IsInitialized())
- {
- m_omx_resize.SetStateForComponent(OMX_StateIdle);
- m_omx_resize.FlushOutput();
- m_omx_resize.FreeOutputBuffers();
- }
- }
- if(m_omx_tunnel_decode.IsInitialized())
- m_omx_tunnel_decode.Deestablish();
- if(m_omx_decoder.IsInitialized())
- m_omx_decoder.Deinitialize();
- if(m_omx_resize.IsInitialized())
- m_omx_resize.Deinitialize();
-}
-
-bool COMXImageDec::HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, unsigned int resize_stride)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- // on the first port settings changed event, we create the tunnel and alloc the buffer
- if (!m_decoded_buffer)
- {
- OMX_PARAM_PORTDEFINITIONTYPE port_def;
- OMX_INIT_STRUCTURE(port_def);
-
- port_def.nPortIndex = m_omx_decoder.GetOutputPort();
- m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- port_def.format.image.nSliceHeight = 16;
- m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
-
- port_def.nPortIndex = m_omx_resize.GetInputPort();
- m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
-
- m_omx_tunnel_decode.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_resize, m_omx_resize.GetInputPort());
-
- omx_err = m_omx_tunnel_decode.Establish();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_decode.Establish", CLASSNAME, __func__);
- return false;
- }
- omx_err = m_omx_resize.WaitForEvent(OMX_EventPortSettingsChanged);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.WaitForEvent=%x", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- port_def.nPortIndex = m_omx_resize.GetOutputPort();
- m_omx_resize.GetParameter(OMX_IndexParamPortDefinition, &port_def);
-
- port_def.nPortIndex = m_omx_resize.GetOutputPort();
- port_def.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
- port_def.format.image.eColorFormat = OMX_COLOR_Format32bitARGB8888;
- port_def.format.image.nFrameWidth = resize_width;
- port_def.format.image.nFrameHeight = resize_height;
- port_def.format.image.nStride = resize_stride;
- port_def.format.image.nSliceHeight = 0;
- port_def.format.image.bFlagErrorConcealment = OMX_FALSE;
-
- omx_err = m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- OMX_INIT_STRUCTURE(m_decoded_format);
- m_decoded_format.nPortIndex = m_omx_resize.GetOutputPort();
- omx_err = m_omx_resize.GetParameter(OMX_IndexParamPortDefinition, &m_decoded_format);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
- assert(m_decoded_format.nBufferCountActual == 1);
-
- omx_err = m_omx_resize.AllocOutputBuffers();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.AllocOutputBuffers result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
- omx_err = m_omx_resize.SetStateForComponent(OMX_StateExecuting);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetStateForComponent result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
-
- m_decoded_buffer = m_omx_resize.GetOutputBuffer();
-
- if(!m_decoded_buffer)
- {
- CLog::Log(LOGERROR, "%s::%s no output buffer", CLASSNAME, __func__);
- return false;
- }
-
- omx_err = m_omx_resize.FillThisBuffer(m_decoded_buffer);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize FillThisBuffer result(0x%x)", CLASSNAME, __func__,
- omx_err);
- m_omx_resize.DecoderFillBufferDone(m_omx_resize.GetComponent(), m_decoded_buffer);
- return false;
- }
- }
- // on subsequent port settings changed event, we just copy the port settings
- else
- {
- // a little surprising, make a note
- CLog::Log(LOGDEBUG, "%s::%s m_omx_resize second port changed event", CLASSNAME, __func__);
- m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), true);
- m_omx_resize.DisablePort(m_omx_resize.GetInputPort(), true);
-
- OMX_PARAM_PORTDEFINITIONTYPE port_def;
- OMX_INIT_STRUCTURE(port_def);
-
- port_def.nPortIndex = m_omx_decoder.GetOutputPort();
- m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- port_def.nPortIndex = m_omx_resize.GetInputPort();
- m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
-
- omx_err = m_omx_resize.WaitForEvent(OMX_EventPortSettingsChanged);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.WaitForEvent=%x", CLASSNAME, __func__, omx_err);
- return false;
- }
- m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), true);
- m_omx_resize.EnablePort(m_omx_resize.GetInputPort(), true);
- }
- return true;
-}
-
-bool COMXImageDec::Decode(const uint8_t *demuxer_content, unsigned demuxer_bytes, unsigned width, unsigned height, unsigned stride, void *pixels)
-{
- CSingleLock lock(m_OMXSection);
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- OMX_BUFFERHEADERTYPE *omx_buffer = NULL;
-
- if(!demuxer_content || !demuxer_bytes)
- {
- CLog::Log(LOGERROR, "%s::%s no input buffer", CLASSNAME, __func__);
- return false;
- }
-
- if(!m_omx_decoder.Initialize("OMX.broadcom.image_decode", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_decoder.Initialize", CLASSNAME, __func__);
- return false;
- }
-
- if(!m_omx_resize.Initialize("OMX.broadcom.resize", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_resize.Initialize", CLASSNAME, __func__);
- return false;
- }
-
- // set input format
- OMX_PARAM_PORTDEFINITIONTYPE portParam;
- OMX_INIT_STRUCTURE(portParam);
- portParam.nPortIndex = m_omx_decoder.GetInputPort();
-
- omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &portParam);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error GetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)",
- CLASSNAME, __func__, omx_err);
- return false;
- }
-
- portParam.nBufferCountActual = portParam.nBufferCountMin;
- portParam.nBufferSize = std::max(portParam.nBufferSize, ALIGN_UP(demuxer_bytes, portParam.nBufferAlignment));
- portParam.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
-
- omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &portParam);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error SetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)",
- CLASSNAME, __func__, omx_err);
- return false;
- }
-
- omx_err = m_omx_decoder.AllocInputBuffers();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_decoder.AllocInputBuffers result(0x%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- omx_err = m_omx_decoder.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_decoder.SetStateForComponent result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
-
- while(demuxer_bytes > 0 || !m_decoded_buffer)
- {
- long timeout = 0;
- if (demuxer_bytes)
- {
- omx_buffer = m_omx_decoder.GetInputBuffer(1000);
- if(omx_buffer == NULL)
- return false;
-
- omx_buffer->nOffset = omx_buffer->nFlags = 0;
-
- omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes;
- memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen);
-
- demuxer_content += omx_buffer->nFilledLen;
- demuxer_bytes -= omx_buffer->nFilledLen;
-
- if(demuxer_bytes == 0)
- omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
-
- omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s OMX_EmptyThisBuffer() failed with result(0x%x)", CLASSNAME,
- __func__, omx_err);
- m_omx_decoder.DecoderEmptyBufferDone(m_omx_decoder.GetComponent(), omx_buffer);
- return false;
- }
- }
- if (!demuxer_bytes)
- {
- // we've submitted all buffers so can wait now
- timeout = 1000;
- }
- omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, timeout);
- if(omx_err == OMX_ErrorNone)
- {
- if (!HandlePortSettingChange(width, height, stride))
- {
- CLog::Log(LOGERROR, "%s::%s HandlePortSettingChange() failed", CLASSNAME, __func__);
- return false;
- }
- }
- else if(omx_err == OMX_ErrorStreamCorrupt)
- {
- CLog::Log(LOGERROR, "%s::%s - image not supported", CLASSNAME, __func__);
- return false;
- }
- else if(timeout || omx_err != OMX_ErrorTimeout)
- {
- CLog::Log(LOGERROR, "%s::%s WaitForEvent:OMX_EventPortSettingsChanged failed (%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
- }
-
- omx_err = m_omx_resize.WaitForOutputDone(1000);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.WaitForOutputDone result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- if(m_omx_decoder.BadState())
- return false;
-
- memcpy( (char*)pixels, m_decoded_buffer->pBuffer, stride * height);
-
- m_success = true;
- Close();
- return true;
-}
-
-#ifdef CLASSNAME
-#undef CLASSNAME
-#endif
-#define CLASSNAME "COMXImageEnc"
-
-COMXImageEnc::COMXImageEnc()
-{
- limit_calls_enter();
- CSingleLock lock(m_OMXSection);
- OMX_INIT_STRUCTURE(m_encoded_format);
- m_encoded_buffer = NULL;
- m_success = false;
-}
-
-COMXImageEnc::~COMXImageEnc()
-{
- CSingleLock lock(m_OMXSection);
-
- OMX_INIT_STRUCTURE(m_encoded_format);
- m_encoded_buffer = NULL;
- if (!m_success)
- {
- if(m_omx_encoder.IsInitialized())
- {
- m_omx_encoder.SetStateForComponent(OMX_StateIdle);
- m_omx_encoder.FlushAll();
- m_omx_encoder.FreeInputBuffers();
- m_omx_encoder.FreeOutputBuffers();
- m_omx_encoder.Deinitialize();
- }
- }
- limit_calls_leave();
-}
-
-bool COMXImageEnc::Encode(unsigned char *buffer, int size, unsigned width, unsigned height, unsigned int pitch)
-{
- CSingleLock lock(m_OMXSection);
-
- unsigned int demuxer_bytes = 0;
- const uint8_t *demuxer_content = NULL;
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- OMX_BUFFERHEADERTYPE *omx_buffer = NULL;
- OMX_INIT_STRUCTURE(m_encoded_format);
-
- if (pitch == 0)
- pitch = 4 * width;
-
- if (!buffer || !size)
- {
- CLog::Log(LOGERROR, "%s::%s error no buffer", CLASSNAME, __func__);
- return false;
- }
-
- if(!m_omx_encoder.Initialize("OMX.broadcom.image_encode", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_encoder.Initialize", CLASSNAME, __func__);
- return false;
- }
-
- OMX_PARAM_PORTDEFINITIONTYPE port_def;
- OMX_INIT_STRUCTURE(port_def);
- port_def.nPortIndex = m_omx_encoder.GetInputPort();
-
- omx_err = m_omx_encoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- port_def.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
- port_def.format.image.eColorFormat = OMX_COLOR_Format32bitARGB8888;
- port_def.format.image.nFrameWidth = width;
- port_def.format.image.nFrameHeight = height;
- port_def.format.image.nStride = pitch;
- port_def.format.image.nSliceHeight = (height+15) & ~15;
- port_def.format.image.bFlagErrorConcealment = OMX_FALSE;
-
- omx_err = m_omx_encoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- OMX_INIT_STRUCTURE(port_def);
- port_def.nPortIndex = m_omx_encoder.GetOutputPort();
-
- omx_err = m_omx_encoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- port_def.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
- port_def.format.image.eColorFormat = OMX_COLOR_FormatUnused;
- port_def.format.image.nFrameWidth = width;
- port_def.format.image.nFrameHeight = height;
- port_def.format.image.nStride = 0;
- port_def.format.image.nSliceHeight = 0;
- port_def.format.image.bFlagErrorConcealment = OMX_FALSE;
-
- omx_err = m_omx_encoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- OMX_IMAGE_PARAM_QFACTORTYPE qfactor;
- OMX_INIT_STRUCTURE(qfactor);
- qfactor.nPortIndex = m_omx_encoder.GetOutputPort();
- qfactor.nQFactor = 16;
-
- omx_err = m_omx_encoder.SetParameter(OMX_IndexParamQFactor, &qfactor);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetParameter OMX_IndexParamQFactor result(0x%x)",
- CLASSNAME, __func__, omx_err);
- return false;
- }
-
- omx_err = m_omx_encoder.AllocInputBuffers();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.AllocInputBuffers result(0x%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- omx_err = m_omx_encoder.AllocOutputBuffers();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.AllocOutputBuffers result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- omx_err = m_omx_encoder.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetStateForComponent result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
-
- demuxer_content = buffer;
- demuxer_bytes = height * pitch;
-
- if(!demuxer_bytes || !demuxer_content)
- return false;
-
- while(demuxer_bytes > 0)
- {
- omx_buffer = m_omx_encoder.GetInputBuffer(1000);
- if(omx_buffer == NULL)
- {
- return false;
- }
-
- omx_buffer->nOffset = omx_buffer->nFlags = 0;
-
- omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes;
- memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen);
-
- demuxer_content += omx_buffer->nFilledLen;
- demuxer_bytes -= omx_buffer->nFilledLen;
-
- if(demuxer_bytes == 0)
- omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
-
- omx_err = m_omx_encoder.EmptyThisBuffer(omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s OMX_EmptyThisBuffer() failed with result(0x%x)", CLASSNAME,
- __func__, omx_err);
- m_omx_encoder.DecoderEmptyBufferDone(m_omx_encoder.GetComponent(), omx_buffer);
- break;
- }
- }
-
- m_encoded_buffer = m_omx_encoder.GetOutputBuffer();
-
- if(!m_encoded_buffer)
- {
- CLog::Log(LOGERROR, "%s::%s no output buffer", CLASSNAME, __func__);
- return false;
- }
-
- omx_err = m_omx_encoder.FillThisBuffer(m_encoded_buffer);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.FillThisBuffer result(0x%x)", CLASSNAME, __func__,
- omx_err);
- m_omx_encoder.DecoderFillBufferDone(m_omx_encoder.GetComponent(), m_encoded_buffer);
- return false;
- }
- omx_err = m_omx_encoder.WaitForOutputDone(2000);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.WaitForOutputDone result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- m_encoded_format.nPortIndex = m_omx_encoder.GetOutputPort();
- omx_err = m_omx_encoder.GetParameter(OMX_IndexParamPortDefinition, &m_encoded_format);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- if(m_omx_encoder.BadState())
- return false;
-
- return true;
-}
-
-bool COMXImageEnc::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
- unsigned int format, unsigned int pitch, const std::string& destFile)
-{
- if(format != XB_FMT_A8R8G8B8 || !buffer)
- {
- CLog::Log(LOGDEBUG, "%s::%s : %s failed format=0x%x", CLASSNAME, __func__, destFile.c_str(),
- format);
- return false;
- }
-
- if(!Encode(buffer, height * pitch, width, height, pitch))
- {
- CLog::Log(LOGDEBUG, "%s::%s : %s encode failed", CLASSNAME, __func__, destFile.c_str());
- return false;
- }
-
- XFILE::CFile file;
- if (file.OpenForWrite(destFile, true))
- {
- CLog::Log(LOGDEBUG, "%s::%s : %s width %d height %d", CLASSNAME, __func__, destFile.c_str(),
- width, height);
-
- file.Write(m_encoded_buffer->pBuffer, m_encoded_buffer->nFilledLen);
- file.Close();
- return true;
- }
-
- m_success = true;
- return false;
-}
-
-#ifdef CLASSNAME
-#undef CLASSNAME
-#endif
-#define CLASSNAME "COMXReEnc"
-
-COMXImageReEnc::COMXImageReEnc()
-{
- limit_calls_enter();
- m_encoded_buffer = NULL;
- m_pDestBuffer = NULL;
- m_nDestAllocSize = 0;
- m_success = false;
-}
-
-COMXImageReEnc::~COMXImageReEnc()
-{
- Close();
- if (m_pDestBuffer)
- free (m_pDestBuffer);
- m_pDestBuffer = NULL;
- m_nDestAllocSize = 0;
- limit_calls_leave();
-}
-
-void COMXImageReEnc::Close()
-{
- CSingleLock lock(m_OMXSection);
-
- if (!m_success)
- {
- if(m_omx_decoder.IsInitialized())
- {
- m_omx_decoder.SetStateForComponent(OMX_StateIdle);
- m_omx_decoder.FlushInput();
- m_omx_decoder.FreeInputBuffers();
- }
- if(m_omx_resize.IsInitialized())
- {
- m_omx_resize.SetStateForComponent(OMX_StateIdle);
- }
- if(m_omx_encoder.IsInitialized())
- {
- m_omx_encoder.SetStateForComponent(OMX_StateIdle);
- m_omx_encoder.FlushOutput();
- m_omx_encoder.FreeOutputBuffers();
- }
- }
- if(m_omx_tunnel_decode.IsInitialized())
- m_omx_tunnel_decode.Deestablish();
- if(m_omx_tunnel_resize.IsInitialized())
- m_omx_tunnel_resize.Deestablish();
- if(m_omx_decoder.IsInitialized())
- m_omx_decoder.Deinitialize();
- if(m_omx_resize.IsInitialized())
- m_omx_resize.Deinitialize();
- if(m_omx_encoder.IsInitialized())
- m_omx_encoder.Deinitialize();
-}
-
-
-
-bool COMXImageReEnc::HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, int orientation, bool port_settings_changed)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- // on the first port settings changed event, we create the tunnel and alloc the buffer
- if (!port_settings_changed)
- {
- OMX_PARAM_PORTDEFINITIONTYPE port_def;
- OMX_INIT_STRUCTURE(port_def);
-
- port_def.nPortIndex = m_omx_decoder.GetOutputPort();
- m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_decoder.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- if (resize_width != port_def.format.image.nFrameWidth || resize_height != port_def.format.image.nFrameHeight || (orientation & 4))
- {
- if(!m_omx_resize.Initialize("OMX.broadcom.resize", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_resize.Initialize", CLASSNAME, __func__);
- return false;
- }
- }
-
- //! @todo jpeg decoder can decimate by factors of 2
- port_def.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
- if (m_omx_resize.IsInitialized())
- port_def.format.image.nSliceHeight = 16;
- else
- port_def.format.image.nSliceHeight = (resize_height+15) & ~15;
-
- port_def.format.image.nStride = 0;
-
- m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_decoder.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- if (m_omx_resize.IsInitialized())
- {
- port_def.nPortIndex = m_omx_resize.GetInputPort();
-
- m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- port_def.nPortIndex = m_omx_resize.GetOutputPort();
- m_omx_resize.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
- port_def.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
- port_def.format.image.nFrameWidth = resize_width;
- port_def.format.image.nFrameHeight = resize_height;
- port_def.format.image.nSliceHeight = (resize_height+15) & ~15;
- port_def.format.image.nStride = 0;
- m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
- }
-
- if(!m_omx_encoder.Initialize("OMX.broadcom.image_encode", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_encoder.Initialize", CLASSNAME, __func__);
- return false;
- }
-
- port_def.nPortIndex = m_omx_encoder.GetInputPort();
- m_omx_encoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
- port_def.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
- port_def.format.image.nFrameWidth = resize_width;
- port_def.format.image.nFrameHeight = resize_height;
- port_def.format.image.nSliceHeight = (resize_height+15) & ~15;
- port_def.format.image.nStride = 0;
- m_omx_encoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- port_def.nPortIndex = m_omx_encoder.GetOutputPort();
- omx_err = m_omx_encoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- port_def.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
- port_def.format.image.eColorFormat = OMX_COLOR_FormatUnused;
- port_def.format.image.nFrameWidth = resize_width;
- port_def.format.image.nFrameHeight = resize_height;
- port_def.format.image.nStride = 0;
- port_def.format.image.nSliceHeight = 0;
- port_def.format.image.bFlagErrorConcealment = OMX_FALSE;
-
- omx_err = m_omx_encoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- OMX_IMAGE_PARAM_QFACTORTYPE qfactor;
- OMX_INIT_STRUCTURE(qfactor);
- qfactor.nPortIndex = m_omx_encoder.GetOutputPort();
- qfactor.nQFactor = 16;
-
- omx_err = m_omx_encoder.SetParameter(OMX_IndexParamQFactor, &qfactor);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetParameter OMX_IndexParamQFactor result(0x%x)",
- CLASSNAME, __func__, omx_err);
- return false;
- }
-
- if (orientation)
- {
- struct {
- // metadata, these two fields need to be together
- OMX_CONFIG_METADATAITEMTYPE metadata;
- char metadata_space[64];
- } item;
- OMX_INIT_STRUCTURE(item.metadata);
-
- item.metadata.nSize = sizeof(item);
- item.metadata.eScopeMode = OMX_MetadataScopePortLevel;
- item.metadata.nScopeSpecifier = m_omx_encoder.GetOutputPort();
- item.metadata.nMetadataItemIndex = 0;
- item.metadata.eSearchMode = OMX_MetadataSearchValueSizeByIndex;
- item.metadata.eKeyCharset = OMX_MetadataCharsetASCII;
- strcpy((char *)item.metadata.nKey, "IFD0.Orientation");
- item.metadata.nKeySizeUsed = strlen((char *)item.metadata.nKey);
-
- item.metadata.eValueCharset = OMX_MetadataCharsetASCII;
- item.metadata.sLanguageCountry = 0;
- item.metadata.nValueMaxSize = sizeof(item.metadata_space);
- sprintf((char *)item.metadata.nValue, "%d", orientation + 1);
- item.metadata.nValueSizeUsed = strlen((char *)item.metadata.nValue);
-
- omx_err = m_omx_encoder.SetParameter(OMX_IndexConfigMetadataItem, &item);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "%s::%s m_omx_encoder.SetParameter:OMX_IndexConfigMetadataItem omx_err(0x%08x)",
- CLASSNAME, __func__, omx_err);
- return false;
- }
- }
- omx_err = m_omx_encoder.AllocOutputBuffers();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.AllocOutputBuffers result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
-
- if (m_omx_resize.IsInitialized())
- {
- m_omx_tunnel_decode.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_resize, m_omx_resize.GetInputPort());
-
- omx_err = m_omx_tunnel_decode.Establish();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_decode.Establish", CLASSNAME, __func__);
- return false;
- }
-
- m_omx_tunnel_resize.Initialize(&m_omx_resize, m_omx_resize.GetOutputPort(), &m_omx_encoder, m_omx_encoder.GetInputPort());
-
- omx_err = m_omx_tunnel_resize.Establish();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_resize.Establish", CLASSNAME, __func__);
- return false;
- }
-
- omx_err = m_omx_resize.SetStateForComponent(OMX_StateExecuting);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetStateForComponent result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
- }
- else
- {
- m_omx_tunnel_decode.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_encoder, m_omx_encoder.GetInputPort());
-
- omx_err = m_omx_tunnel_decode.Establish();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_decode.Establish", CLASSNAME, __func__);
- return false;
- }
- }
- omx_err = m_omx_encoder.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_encoder.SetStateForComponent result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
-
- if(m_omx_encoder.BadState())
- return false;
- }
- // on subsequent port settings changed event, we just copy the port settings
- else
- {
- // a little surprising, make a note
- CLog::Log(LOGDEBUG, "%s::%s m_omx_resize second port changed event", CLASSNAME, __func__);
- m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), true);
- if (m_omx_resize.IsInitialized())
- {
- m_omx_resize.DisablePort(m_omx_resize.GetInputPort(), true);
-
- OMX_PARAM_PORTDEFINITIONTYPE port_def;
- OMX_INIT_STRUCTURE(port_def);
-
- port_def.nPortIndex = m_omx_decoder.GetOutputPort();
- m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- port_def.nPortIndex = m_omx_resize.GetInputPort();
- m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
-
- omx_err = m_omx_resize.WaitForEvent(OMX_EventPortSettingsChanged);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.WaitForEvent=%x", CLASSNAME, __func__, omx_err);
- return false;
- }
- m_omx_resize.EnablePort(m_omx_resize.GetInputPort(), true);
- }
- m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), true);
- }
- return true;
-}
-
-bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, unsigned int maxHeight, void * &pDestBuffer, unsigned int &nDestSize)
-{
- CSingleLock lock(m_OMXSection);
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- COMXImage::ClampLimits(maxWidth, maxHeight, srcFile.GetWidth(), srcFile.GetHeight(), srcFile.GetOrientation() & 4);
- unsigned int demuxer_bytes = srcFile.GetImageSize();
- unsigned char *demuxer_content = (unsigned char *)srcFile.GetImageBuffer();
- // initial dest buffer size
- nDestSize = 0;
-
- if(!demuxer_content || !demuxer_bytes)
- {
- CLog::Log(LOGERROR, "%s::%s %s no input buffer", CLASSNAME, __func__, srcFile.GetFilename());
- return false;
- }
-
- if(!m_omx_decoder.Initialize("OMX.broadcom.image_decode", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s %s error m_omx_decoder.Initialize", CLASSNAME, __func__,
- srcFile.GetFilename());
- return false;
- }
-
- // set input format
- OMX_PARAM_PORTDEFINITIONTYPE portParam;
- OMX_INIT_STRUCTURE(portParam);
- portParam.nPortIndex = m_omx_decoder.GetInputPort();
-
- omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &portParam);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s %s error GetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)",
- CLASSNAME, __func__, srcFile.GetFilename(), omx_err);
- return false;
- }
-
- portParam.nBufferCountActual = portParam.nBufferCountMin;
- portParam.nBufferSize = std::max(portParam.nBufferSize, ALIGN_UP(demuxer_bytes, portParam.nBufferAlignment));
- portParam.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
-
- omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &portParam);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s %s error SetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)",
- CLASSNAME, __func__, srcFile.GetFilename(), omx_err);
- return false;
- }
-
- omx_err = m_omx_decoder.AllocInputBuffers();
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s %s m_omx_decoder.AllocInputBuffers result(0x%x)", CLASSNAME, __func__, srcFile.GetFilename(), omx_err);
- return false;
- }
-
- omx_err = m_omx_decoder.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s %s m_omx_decoder.SetStateForComponent result(0x%x)", CLASSNAME,
- __func__, srcFile.GetFilename(), omx_err);
- return false;
- }
-
- bool port_settings_changed = false, eos = false;
- while(demuxer_bytes > 0 || !port_settings_changed || !eos)
- {
- long timeout = 0;
- if (demuxer_bytes)
- {
- OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(1000);
- if(omx_buffer)
- {
- omx_buffer->nOffset = omx_buffer->nFlags = 0;
-
- omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes;
- memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen);
-
- demuxer_content += omx_buffer->nFilledLen;
- demuxer_bytes -= omx_buffer->nFilledLen;
- if(demuxer_bytes == 0)
- omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
-
- omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s %s OMX_EmptyThisBuffer() failed with result(0x%x)",
- CLASSNAME, __func__, srcFile.GetFilename(), omx_err);
- m_omx_decoder.DecoderEmptyBufferDone(m_omx_decoder.GetComponent(), omx_buffer);
- return false;
- }
- }
- }
- if (!demuxer_bytes)
- {
- // we've submitted all buffers so can wait now
- timeout = 1000;
- }
-
- omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, timeout);
- if(omx_err == OMX_ErrorNone)
- {
- if (!HandlePortSettingChange(maxWidth, maxHeight, srcFile.GetOrientation(), port_settings_changed))
- {
- CLog::Log(LOGERROR, "%s::%s %s HandlePortSettingChange() failed", srcFile.GetFilename(),
- CLASSNAME, __func__);
- return false;
- }
- port_settings_changed = true;
- }
- else if(omx_err == OMX_ErrorStreamCorrupt)
- {
- CLog::Log(LOGERROR, "%s::%s %s - image not supported", CLASSNAME, __func__, srcFile.GetFilename());
- return false;
- }
- else if(timeout || omx_err != OMX_ErrorTimeout)
- {
- CLog::Log(LOGERROR, "%s::%s %s WaitForEvent:OMX_EventPortSettingsChanged failed (%x)",
- CLASSNAME, __func__, srcFile.GetFilename(), omx_err);
- return false;
- }
-
- if (!m_encoded_buffer && port_settings_changed && demuxer_bytes == 0)
- {
- m_encoded_buffer = m_omx_encoder.GetOutputBuffer();
- omx_err = m_omx_encoder.FillThisBuffer(m_encoded_buffer);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s %s FillThisBuffer() failed (%x)", CLASSNAME, __func__,
- srcFile.GetFilename(), omx_err);
- m_omx_encoder.DecoderFillBufferDone(m_omx_encoder.GetComponent(), m_encoded_buffer);
- return false;
- }
- }
- if (m_encoded_buffer)
- {
- omx_err = m_omx_encoder.WaitForOutputDone(2000);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s %s m_omx_encoder.WaitForOutputDone result(0x%x)", CLASSNAME,
- __func__, srcFile.GetFilename(), omx_err);
- return false;
- }
- if (!m_encoded_buffer->nFilledLen)
- {
- CLog::Log(LOGERROR, "%s::%s %s m_omx_encoder.WaitForOutputDone no data", CLASSNAME,
- __func__, srcFile.GetFilename());
- return false;
- }
- if (m_encoded_buffer->nFlags & OMX_BUFFERFLAG_EOS)
- eos = true;
-
- if (nDestSize + m_encoded_buffer->nFilledLen > m_nDestAllocSize)
- {
- while (nDestSize + m_encoded_buffer->nFilledLen > m_nDestAllocSize)
- m_nDestAllocSize = std::max(1024U*1024U, m_nDestAllocSize*2);
- m_pDestBuffer = realloc(m_pDestBuffer, m_nDestAllocSize);
- }
- memcpy((char *)m_pDestBuffer + nDestSize, m_encoded_buffer->pBuffer, m_encoded_buffer->nFilledLen);
- nDestSize += m_encoded_buffer->nFilledLen;
- m_encoded_buffer = NULL;
- }
- }
-
- if(m_omx_decoder.BadState())
- return false;
-
- pDestBuffer = m_pDestBuffer;
- CLog::Log(LOGDEBUG, "%s::%s : %s %dx%d -> %dx%d", CLASSNAME, __func__, srcFile.GetFilename(),
- srcFile.GetWidth(), srcFile.GetHeight(), maxWidth, maxHeight);
-
- m_success = true;
- Close();
-
- return true;
-}
-
-
-#ifdef CLASSNAME
-#undef CLASSNAME
-#endif
-#define CLASSNAME "COMXTexture"
-
-COMXTexture::COMXTexture()
-{
- limit_calls_enter();
- m_success = false;
-}
-
-COMXTexture::~COMXTexture()
-{
- Close();
- limit_calls_leave();
-}
-
-void COMXTexture::Close()
-{
- CSingleLock lock(m_OMXSection);
-
- if (!m_success)
- {
- if(m_omx_decoder.IsInitialized())
- {
- m_omx_decoder.SetStateForComponent(OMX_StateIdle);
- m_omx_decoder.FlushInput();
- m_omx_decoder.FreeInputBuffers();
- }
- if(m_omx_egl_render.IsInitialized())
- {
- m_omx_egl_render.SetStateForComponent(OMX_StateIdle);
- m_omx_egl_render.FlushOutput();
- m_omx_egl_render.FreeOutputBuffers();
- }
- }
- if (m_omx_tunnel_decode.IsInitialized())
- m_omx_tunnel_decode.Deestablish();
- if (m_omx_tunnel_egl.IsInitialized())
- m_omx_tunnel_egl.Deestablish();
- // delete components
- if (m_omx_decoder.IsInitialized())
- m_omx_decoder.Deinitialize();
- if (m_omx_resize.IsInitialized())
- m_omx_resize.Deinitialize();
- if (m_omx_egl_render.IsInitialized())
- m_omx_egl_render.Deinitialize();
-}
-
-bool COMXTexture::HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, void *egl_image, bool port_settings_changed)
-{
- CWinSystemRpiGLESContext *winsystem = static_cast<CWinSystemRpiGLESContext *>(CServiceBroker::GetWinSystem());
- EGLDisplay egl_display = winsystem->GetEGLDisplay();
- OMX_ERRORTYPE omx_err;
-
- if (port_settings_changed)
- CLog::Log(LOGERROR, "%s::%s Unexpected second port_settings_changed call", CLASSNAME, __func__);
-
- OMX_PARAM_PORTDEFINITIONTYPE port_def;
- OMX_INIT_STRUCTURE(port_def);
-
- port_def.nPortIndex = m_omx_decoder.GetOutputPort();
- omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_decoder.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- //! @todo jpeg decoder can decimate by factors of 2
- port_def.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
- port_def.format.image.nSliceHeight = 16;
- port_def.format.image.nStride = 0;
-
- omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_decoder.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
- if (resize_width != port_def.format.image.nFrameWidth || resize_height != port_def.format.image.nFrameHeight)
- {
- if (!m_omx_resize.Initialize("OMX.broadcom.resize", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_resize.Initialize", CLASSNAME, __func__);
- return false;
- }
- }
- if (m_omx_resize.IsInitialized())
- {
- port_def.nPortIndex = m_omx_resize.GetInputPort();
-
- omx_err = m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- port_def.nPortIndex = m_omx_resize.GetOutputPort();
- omx_err = m_omx_resize.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.GetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- port_def.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
- port_def.format.image.nFrameWidth = resize_width;
- port_def.format.image.nFrameHeight = resize_height;
- port_def.format.image.nSliceHeight = 16;
- port_def.format.image.nStride = 0;
- omx_err = m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
- }
- if (!m_omx_egl_render.Initialize("OMX.broadcom.egl_render", OMX_IndexParamVideoInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.Initialize", CLASSNAME, __func__);
- return false;
- }
-
- port_def.nPortIndex = m_omx_egl_render.GetOutputPort();
- omx_err = m_omx_egl_render.GetParameter(OMX_IndexParamPortDefinition, &port_def);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_egl_render.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
- port_def.nBufferCountActual = 1;
- port_def.format.video.pNativeWindow = egl_display;
-
- omx_err = m_omx_egl_render.SetParameter(OMX_IndexParamPortDefinition, &port_def);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_egl_render.SetParameter result(0x%x)", CLASSNAME, __func__,
- omx_err);
- return false;
- }
-
- omx_err = m_omx_egl_render.UseEGLImage(&m_egl_buffer, m_omx_egl_render.GetOutputPort(), NULL, egl_image);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.UseEGLImage (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
- if (m_omx_resize.IsInitialized())
- {
- m_omx_tunnel_decode.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_resize, m_omx_resize.GetInputPort());
-
- omx_err = m_omx_tunnel_decode.Establish();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_decode.Establish (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- m_omx_tunnel_egl.Initialize(&m_omx_resize, m_omx_resize.GetOutputPort(), &m_omx_egl_render, m_omx_egl_render.GetInputPort());
-
- omx_err = m_omx_tunnel_egl.Establish();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_egl.Establish (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- omx_err = m_omx_resize.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.GetParameter (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
- }
- else
- {
- m_omx_tunnel_decode.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_egl_render, m_omx_egl_render.GetInputPort());
-
- omx_err = m_omx_tunnel_decode.Establish();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_decode.Establish (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
- }
-
- omx_err = m_omx_egl_render.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.SetStateForComponent (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- return true;
-}
-
-bool COMXTexture::Decode(const uint8_t *demuxer_content, unsigned demuxer_bytes, unsigned int width, unsigned int height, void *egl_image)
-{
- CSingleLock lock(m_OMXSection);
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if (!demuxer_content || !demuxer_bytes)
- {
- CLog::Log(LOGERROR, "%s::%s no input buffer", CLASSNAME, __func__);
- return false;
- }
-
- if (!m_omx_decoder.Initialize("OMX.broadcom.image_decode", OMX_IndexParamImageInit))
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_decoder.Initialize", CLASSNAME, __func__);
- return false;
- }
-
- // set input format
- OMX_PARAM_PORTDEFINITIONTYPE portParam;
- OMX_INIT_STRUCTURE(portParam);
- portParam.nPortIndex = m_omx_decoder.GetInputPort();
-
- omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &portParam);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error GetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)",
- CLASSNAME, __func__, omx_err);
- return false;
- }
-
- portParam.nBufferCountActual = portParam.nBufferCountMin;
- portParam.nBufferSize = std::max(portParam.nBufferSize, ALIGN_UP(demuxer_bytes, portParam.nBufferAlignment));
- portParam.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
-
- omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &portParam);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error SetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)",
- CLASSNAME, __func__, omx_err);
- return false;
- }
-
- omx_err = m_omx_decoder.AllocInputBuffers();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s - Error alloc buffers (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- omx_err = m_omx_decoder.SetStateForComponent(OMX_StateExecuting);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_sched.SetStateForComponent (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
-
- bool port_settings_changed = false;
- bool eos = false;
- while(demuxer_bytes > 0 || !port_settings_changed || !eos)
- {
- long timeout = 0;
- if (demuxer_bytes)
- {
- OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(1000);
- if (omx_buffer)
- {
- omx_buffer->nOffset = omx_buffer->nFlags = 0;
-
- omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes;
- memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen);
-
- demuxer_content += omx_buffer->nFilledLen;
- demuxer_bytes -= omx_buffer->nFilledLen;
-
- if (demuxer_bytes == 0)
- omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
-
- omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s - m_omx_decoder.OMX_EmptyThisBuffer (%x)", CLASSNAME, __func__, omx_err);
- m_omx_decoder.DecoderEmptyBufferDone(m_omx_decoder.GetComponent(), omx_buffer);
- return false;
- }
- }
- }
- if (!demuxer_bytes)
- {
- // we've submitted all buffers so can wait now
- timeout = 1000;
- }
-
- omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, timeout);
- if (omx_err == OMX_ErrorNone)
- {
- if (!HandlePortSettingChange(width, height, egl_image, port_settings_changed))
- {
- CLog::Log(LOGERROR, "%s::%s - HandlePortSettingChange failed (%x)", CLASSNAME, __func__, omx_err);
- return false;
- }
- port_settings_changed = true;
- }
- else if (omx_err == OMX_ErrorStreamCorrupt)
- {
- CLog::Log(LOGERROR, "%s::%s - image not supported", CLASSNAME, __func__);
- return false;
- }
- else if (timeout || omx_err != OMX_ErrorTimeout)
- {
- CLog::Log(LOGERROR, "%s::%s WaitForEvent:OMX_EventPortSettingsChanged failed (%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
-
- if (port_settings_changed && m_egl_buffer && demuxer_bytes == 0 && !eos)
- {
- OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_egl_render.GetOutputBuffer();
- if (!omx_buffer)
- {
- CLog::Log(LOGERROR, "%s::%s GetOutputBuffer failed", CLASSNAME, __func__);
- return false;
- }
- if (omx_buffer != m_egl_buffer)
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.GetOutputBuffer (%p,%p)", CLASSNAME,
- __func__, static_cast<void*>(omx_buffer), static_cast<void*>(m_egl_buffer));
- return false;
- }
-
- omx_err = m_omx_egl_render.FillThisBuffer(m_egl_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.FillThisBuffer (%x)", CLASSNAME, __func__, omx_err);
- m_omx_egl_render.DecoderFillBufferDone(m_omx_egl_render.GetComponent(), m_egl_buffer);
- return false;
- }
-
- omx_err = m_omx_egl_render.WaitForOutputDone(2000);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s m_omx_egl_render.WaitForOutputDone result(0x%x)", CLASSNAME,
- __func__, omx_err);
- return false;
- }
- eos = true;
- }
- }
- m_success = true;
- Close();
- return true;
-}
-
-COMXImage g_OMXImage;
diff --git a/xbmc/cores/omxplayer/OMXImage.h b/xbmc/cores/omxplayer/OMXImage.h
deleted file mode 100644
index 474346c18e..0000000000
--- a/xbmc/cores/omxplayer/OMXImage.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2010-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 "OMXCore.h"
-#include "filesystem/File.h"
-#include "guilib/XBTF.h"
-#include "threads/Thread.h"
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <IL/OMX_Video.h>
-
-#include "system_gl.h"
-
-class COMXImageFile;
-
-class COMXImage : public CThread
-{
- struct callbackinfo {
- CEvent sync;
- bool (*callback)(EGLDisplay egl_display, EGLContext egl_context, void *cookie);
- void *cookie;
- bool result;
- };
-protected:
- virtual void OnStartup();
- virtual void OnExit();
- virtual void Process();
-public:
- struct textureinfo {
- int width, height;
- GLuint texture;
- EGLImageKHR egl_image;
- void *parent;
- };
- COMXImage();
- virtual ~COMXImage();
- void Initialize();
- void Deinitialize();
- static COMXImageFile *LoadJpeg(const std::string& texturePath);
- static void CloseJpeg(COMXImageFile *file);
-
- static bool DecodeJpeg(COMXImageFile *file, unsigned int maxWidth, unsigned int maxHeight, unsigned int stride, void *pixels);
- static bool CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
- unsigned int format, unsigned int pitch, const std::string& destFile);
- static bool ClampLimits(unsigned int &width, unsigned int &height, unsigned int m_width, unsigned int m_height, bool transposed = false);
- static bool CreateThumb(const std::string& srcFile, unsigned int width, unsigned int height, std::string &additional_info, const std::string& destFile);
- bool SendMessage(bool (*callback)(EGLDisplay egl_display, EGLContext egl_context, void *cookie), void *cookie);
- bool DecodeJpegToTexture(COMXImageFile *file, unsigned int width, unsigned int height, void **userdata);
- void DestroyTexture(void *userdata);
- void GetTexture(void *userdata, GLuint *texture);
- bool AllocTextureInternal(EGLDisplay egl_display, EGLContext egl_context, struct textureinfo *tex);
- bool DestroyTextureInternal(EGLDisplay egl_display, EGLContext egl_context, struct textureinfo *tex);
-private:
- EGLContext m_egl_context;
-
- void CreateContext();
- EGLContext GetEGLContext();
- CCriticalSection m_texqueue_lock;
- XbmcThreads::ConditionVariable m_texqueue_cond;
- std::queue <struct callbackinfo *> m_texqueue;
-};
-
-class COMXImageFile
-{
-public:
- COMXImageFile();
- virtual ~COMXImageFile();
- bool ReadFile(const std::string& inputFile, int orientation = 0);
- int GetOrientation() const { return m_orientation; };
- unsigned int GetWidth() const { return m_width; };
- unsigned int GetHeight() const { return m_height; };
- unsigned long GetImageSize() const { return m_image_size; };
- const uint8_t *GetImageBuffer() const { return (const uint8_t *)m_image_buffer; };
- const char *GetFilename() const { return m_filename.c_str(); };
-protected:
- OMX_IMAGE_CODINGTYPE GetCodingType(unsigned int &width, unsigned int &height, int orientation);
- uint8_t *m_image_buffer;
- unsigned long m_image_size;
- unsigned int m_width;
- unsigned int m_height;
- int m_orientation;
- std::string m_filename;
-};
-
-class COMXImageDec
-{
-public:
- COMXImageDec();
- virtual ~COMXImageDec();
-
- // Required overrides
- void Close();
- bool Decode(const uint8_t *data, unsigned size, unsigned int width, unsigned int height, unsigned stride, void *pixels);
- unsigned int GetDecodedWidth() const { return (unsigned int)m_decoded_format.format.image.nFrameWidth; };
- unsigned int GetDecodedHeight() const { return (unsigned int)m_decoded_format.format.image.nFrameHeight; };
- unsigned int GetDecodedStride() const { return (unsigned int)m_decoded_format.format.image.nStride; };
-protected:
- bool HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, unsigned int resize_stride);
- // Components
- COMXCoreComponent m_omx_decoder;
- COMXCoreComponent m_omx_resize;
- COMXCoreTunnel m_omx_tunnel_decode;
- OMX_BUFFERHEADERTYPE *m_decoded_buffer;
- OMX_PARAM_PORTDEFINITIONTYPE m_decoded_format;
- CCriticalSection m_OMXSection;
- bool m_success;
-};
-
-class COMXImageEnc
-{
-public:
- COMXImageEnc();
- virtual ~COMXImageEnc();
-
- // Required overrides
- bool CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
- unsigned int format, unsigned int pitch, const std::string& destFile);
-protected:
- bool Encode(unsigned char *buffer, int size, unsigned int width, unsigned int height, unsigned int pitch);
- // Components
- COMXCoreComponent m_omx_encoder;
- OMX_BUFFERHEADERTYPE *m_encoded_buffer;
- OMX_PARAM_PORTDEFINITIONTYPE m_encoded_format;
- CCriticalSection m_OMXSection;
- bool m_success;
-};
-
-class COMXImageReEnc
-{
-public:
- COMXImageReEnc();
- virtual ~COMXImageReEnc();
-
- // Required overrides
- void Close();
- bool ReEncode(COMXImageFile &srcFile, unsigned int width, unsigned int height, void * &pDestBuffer, unsigned int &nDestSize);
-protected:
- bool HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, int orientation, bool port_settings_changed);
- // Components
- COMXCoreComponent m_omx_decoder;
- COMXCoreComponent m_omx_resize;
- COMXCoreComponent m_omx_encoder;
- COMXCoreTunnel m_omx_tunnel_decode;
- COMXCoreTunnel m_omx_tunnel_resize;
- OMX_BUFFERHEADERTYPE *m_encoded_buffer;
- CCriticalSection m_OMXSection;
- void *m_pDestBuffer;
- unsigned int m_nDestAllocSize;
- bool m_success;
-};
-
-class COMXTexture
-{
-public:
- COMXTexture();
- virtual ~COMXTexture();
-
- // Required overrides
- void Close(void);
- bool Decode(const uint8_t *data, unsigned size, unsigned int width, unsigned int height, void *egl_image);
-protected:
- bool HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, void *egl_image, bool port_settings_changed);
-
- // Components
- COMXCoreComponent m_omx_decoder;
- COMXCoreComponent m_omx_resize;
- COMXCoreComponent m_omx_egl_render;
-
- COMXCoreTunnel m_omx_tunnel_decode;
- COMXCoreTunnel m_omx_tunnel_egl;
-
- OMX_BUFFERHEADERTYPE *m_egl_buffer;
- CCriticalSection m_OMXSection;
- bool m_success;
-};
-
-extern COMXImage g_OMXImage;
diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp
index 7f16b37a7e..a3d2c0602b 100644
--- a/xbmc/dbwrappers/Database.cpp
+++ b/xbmc/dbwrappers/Database.cpp
@@ -225,7 +225,6 @@ CDatabase::CDatabase() :
{
m_openCount = 0;
m_sqlite = true;
- m_bMultiWrite = false;
m_multipleExecute = false;
}
@@ -387,14 +386,14 @@ bool CDatabase::QueueInsertQuery(const std::string &strQuery)
if (strQuery.empty())
return false;
- if (!m_bMultiWrite)
+ if (!m_bMultiInsert)
{
if (nullptr == m_pDB)
return false;
if (nullptr == m_pDS2)
return false;
- m_bMultiWrite = true;
+ m_bMultiInsert = true;
m_pDS2->insert();
}
@@ -407,11 +406,11 @@ bool CDatabase::CommitInsertQueries()
{
bool bReturn = true;
- if (m_bMultiWrite)
+ if (m_bMultiInsert)
{
try
{
- m_bMultiWrite = false;
+ m_bMultiInsert = false;
m_pDS2->post();
m_pDS2->clear_insert_sql();
}
@@ -426,6 +425,49 @@ bool CDatabase::CommitInsertQueries()
return bReturn;
}
+size_t CDatabase::GetInsertQueriesCount()
+{
+ return m_pDS2->insert_sql_count();
+}
+
+bool CDatabase::QueueDeleteQuery(const std::string& strQuery)
+{
+ if (strQuery.empty() || !m_pDB || !m_pDS)
+ return false;
+
+ m_bMultiDelete = true;
+ m_pDS->del();
+ m_pDS->add_delete_sql(strQuery);
+ return true;
+}
+
+bool CDatabase::CommitDeleteQueries()
+{
+ bool bReturn = true;
+
+ if (m_bMultiDelete)
+ {
+ try
+ {
+ m_bMultiDelete = false;
+ m_pDS->deletion();
+ m_pDS->clear_delete_sql();
+ }
+ catch (...)
+ {
+ bReturn = false;
+ CLog::Log(LOGERROR, "%s - failed to execute queries", __FUNCTION__);
+ }
+ }
+
+ return bReturn;
+}
+
+size_t CDatabase::GetDeleteQueriesCount()
+{
+ return m_pDS->delete_sql_count();
+}
+
bool CDatabase::Open()
{
DatabaseSettings db_fallback;
diff --git a/xbmc/dbwrappers/Database.h b/xbmc/dbwrappers/Database.h
index ca8fe02ca0..54f905fafd 100644
--- a/xbmc/dbwrappers/Database.h
+++ b/xbmc/dbwrappers/Database.h
@@ -188,6 +188,31 @@ public:
*/
bool CommitInsertQueries();
+ /*!
+ * @brief Get the number of INSERT queries in the queue.
+ * @return The number of queries.
+ */
+ size_t GetInsertQueriesCount();
+
+ /*!
+ * @brief Put a DELETE query in the queue.
+ * @param strQuery The query to queue.
+ * @return True if the query was added successfully, false otherwise.
+ */
+ bool QueueDeleteQuery(const std::string& strQuery);
+
+ /*!
+ * @brief Commit all queued DELETE queries.
+ * @return True if all queries were executed successfully, false otherwise.
+ */
+ bool CommitDeleteQueries();
+
+ /*!
+ * @brief Get the number of DELETE queries in the queue.
+ * @return The number of queries.
+ */
+ size_t GetDeleteQueriesCount();
+
virtual bool GetFilter(CDbUrl &dbUrl, Filter &filter, SortDescription &sorting) { return true; }
virtual bool BuildSQL(const std::string &strBaseDir, const std::string &strQuery, Filter &filter, std::string &strSQL, CDbUrl &dbUrl);
virtual bool BuildSQL(const std::string &strBaseDir, const std::string &strQuery, Filter &filter, std::string &strSQL, CDbUrl &dbUrl, SortDescription &sorting);
@@ -249,7 +274,10 @@ private:
void InitSettings(DatabaseSettings &dbSettings);
void UpdateVersionNumber();
- bool m_bMultiWrite; /*!< True if there are any queries in the queue, false otherwise */
+ bool m_bMultiInsert =
+ false; /*!< True if there are any queries in the insert queue, false otherwise */
+ bool m_bMultiDelete =
+ false; /*!< True if there are any queries in the delete queue, false otherwise */
unsigned int m_openCount;
bool m_multipleExecute;
diff --git a/xbmc/dbwrappers/dataset.cpp b/xbmc/dbwrappers/dataset.cpp
index 334f2045b3..ee0aa635c4 100644
--- a/xbmc/dbwrappers/dataset.cpp
+++ b/xbmc/dbwrappers/dataset.cpp
@@ -293,8 +293,16 @@ void Dataset::post() {
}
-void Dataset::deletion() {
- if (ds_state == dsSelect) make_deletion();
+void Dataset::del()
+{
+ ds_state = dsDelete;
+}
+
+
+void Dataset::deletion()
+{
+ if (ds_state == dsDelete)
+ make_deletion();
}
@@ -518,6 +526,16 @@ void Dataset::clear_delete_sql(){
delete_sql.clear();
}
+size_t Dataset::insert_sql_count()
+{
+ return insert_sql.size();
+}
+
+size_t Dataset::delete_sql_count()
+{
+ return delete_sql.size();
+}
+
int Dataset::field_count() { return fields_object->size();}
int Dataset::fieldCount() { return fields_object->size();}
diff --git a/xbmc/dbwrappers/dataset.h b/xbmc/dbwrappers/dataset.h
index ec87d059ba..6d11a95759 100644
--- a/xbmc/dbwrappers/dataset.h
+++ b/xbmc/dbwrappers/dataset.h
@@ -333,8 +333,10 @@ public:
virtual void append() { insert(); }
/* Start the edit mode */
virtual void edit();
+ /* Start the delete mode */
+ virtual void del();
-/* Add changes, that were made during insert or edit states of dataset into the database */
+ /* Add changes, that were made during insert or edit states of dataset into the database */
virtual void post();
/* Delete statements from database */
virtual void deletion();
@@ -469,8 +471,13 @@ public:
/*clear delete_sql*/
void clear_delete_sql();
-/*get value of select_sql*/
- const char *get_select_sql();
+ /* size of insert_sql*/
+ size_t insert_sql_count();
+ /* size of delete_sql*/
+ size_t delete_sql_count();
+
+ /*get value of select_sql*/
+ const char* get_select_sql();
};
diff --git a/xbmc/filesystem/AddonsDirectory.cpp b/xbmc/filesystem/AddonsDirectory.cpp
index 3d78efa39c..afb172444b 100644
--- a/xbmc/filesystem/AddonsDirectory.cpp
+++ b/xbmc/filesystem/AddonsDirectory.cpp
@@ -502,10 +502,19 @@ static void OutdatedAddons(const CURL& path, CFileItemList &items)
if (!items.IsEmpty())
{
- CFileItemPtr item(new CFileItem("addons://update_all/", false));
- item->SetLabel(g_localizeStrings.Get(24122));
- item->SetSpecialSort(SortSpecialOnTop);
- items.Add(item);
+ if (CAddonSystemSettings::GetInstance().GetAddonAutoUpdateMode() == AUTO_UPDATES_ON)
+ {
+ const CFileItemPtr itemUpdateAllowed(
+ std::make_shared<CFileItem>("addons://update_allowed/", false));
+ itemUpdateAllowed->SetLabel(g_localizeStrings.Get(24137));
+ itemUpdateAllowed->SetSpecialSort(SortSpecialOnTop);
+ items.Add(itemUpdateAllowed);
+ }
+
+ const CFileItemPtr itemUpdateAll(std::make_shared<CFileItem>("addons://update_all/", false));
+ itemUpdateAll->SetLabel(g_localizeStrings.Get(24122));
+ itemUpdateAll->SetSpecialSort(SortSpecialOnTop);
+ items.Add(itemUpdateAll);
}
}
@@ -798,9 +807,10 @@ void CAddonsDirectory::GenerateAddonListing(const CURL& path,
const std::string label,
bool alwaysShowUpdateIcon)
{
- std::set<std::shared_ptr<IAddon>> outdated;
- for (const auto& addon : CServiceBroker::GetAddonMgr().GetOutdatedAddons())
- outdated.insert(addon);
+ std::vector<std::shared_ptr<IAddon>> outdated;
+ std::vector<std::shared_ptr<IAddon>> updates;
+
+ CServiceBroker::GetAddonMgr().GetAvailableUpdatesAndOutdatedAddons(outdated, updates);
items.ClearItems();
items.SetContent("addons");
@@ -815,6 +825,12 @@ void CAddonsDirectory::GenerateAddonListing(const CURL& path,
addon->Version());
bool disabled = CServiceBroker::GetAddonMgr().IsAddonDisabled(addon->ID());
+ bool isUpdate =
+ std::any_of(updates.begin(), updates.end(), [&](const std::shared_ptr<IAddon>& i) {
+ return i->ID() == addon->ID() && i->Origin() == addon->Origin() &&
+ i->Version() == addon->Version();
+ });
+
bool hasUpdate =
alwaysShowUpdateIcon ||
std::any_of(outdated.begin(), outdated.end(), [&](const std::shared_ptr<IAddon>& i) {
@@ -827,6 +843,7 @@ void CAddonsDirectory::GenerateAddonListing(const CURL& path,
pItem->SetProperty("Addon.IsInstalled", installed);
pItem->SetProperty("Addon.IsEnabled", installed && !disabled);
pItem->SetProperty("Addon.HasUpdate", hasUpdate);
+ pItem->SetProperty("Addon.IsUpdate", isUpdate);
pItem->SetProperty("Addon.IsFromOfficialRepo", fromOfficialRepo);
pItem->SetProperty("Addon.IsBinary", addon->IsBinary());
@@ -836,8 +853,10 @@ void CAddonsDirectory::GenerateAddonListing(const CURL& path,
pItem->SetProperty("Addon.Status", g_localizeStrings.Get(24023));
if (hasUpdate)
pItem->SetProperty("Addon.Status", g_localizeStrings.Get(24068));
- else if (addon->IsBroken())
+ else if (addon->LifecycleState() == AddonLifecycleState::BROKEN)
pItem->SetProperty("Addon.Status", g_localizeStrings.Get(24098));
+ else if (addon->LifecycleState() == AddonLifecycleState::DEPRECATED)
+ pItem->SetProperty("Addon.Status", g_localizeStrings.Get(24170));
items.Add(pItem);
}
diff --git a/xbmc/filesystem/FileDirectoryFactory.cpp b/xbmc/filesystem/FileDirectoryFactory.cpp
index 7c7996fa2b..9b088d0e96 100644
--- a/xbmc/filesystem/FileDirectoryFactory.cpp
+++ b/xbmc/filesystem/FileDirectoryFactory.cpp
@@ -20,20 +20,21 @@
#if defined(TARGET_ANDROID)
#include "platform/android/filesystem/APKDirectory.h"
#endif
-#include "XbtDirectory.h"
-#include "ZipDirectory.h"
-#include "SmartPlaylistDirectory.h"
-#include "playlists/SmartPlayList.h"
-#include "PlaylistFileDirectory.h"
-#include "playlists/PlayListFactory.h"
+#include "AudioBookFileDirectory.h"
#include "Directory.h"
#include "FileItem.h"
-#include "utils/StringUtils.h"
-#include "URL.h"
+#include "PlaylistFileDirectory.h"
#include "ServiceBroker.h"
+#include "SmartPlaylistDirectory.h"
+#include "URL.h"
+#include "XbtDirectory.h"
+#include "ZipDirectory.h"
#include "addons/AudioDecoder.h"
#include "addons/VFSEntry.h"
-#include "AudioBookFileDirectory.h"
+#include "playlists/PlayListFactory.h"
+#include "playlists/SmartPlayList.h"
+#include "utils/StringUtils.h"
+#include "utils/log.h"
using namespace ADDON;
using namespace XFILE;
@@ -66,7 +67,11 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem,
if (!result->CreateDecoder() || !result->ContainsFiles(url))
{
delete result;
- return nullptr;
+ CLog::Log(LOGINFO,
+ "CFileDirectoryFactory::{}: Addon '{}' support extension '{}' but creation "
+ "failed (seems not supported), trying other addons and Kodi",
+ __func__, addonInfo->ID(), strExtension);
+ continue;
}
return result;
}
diff --git a/xbmc/filesystem/IFileTypes.h b/xbmc/filesystem/IFileTypes.h
index 734b9adb73..6817752ccd 100644
--- a/xbmc/filesystem/IFileTypes.h
+++ b/xbmc/filesystem/IFileTypes.h
@@ -55,7 +55,6 @@ struct SCacheStatus
};
typedef enum {
- IOCTRL_INVALID = 0, /**< For cases between addon and Kodi where addon bring not supported part */
IOCTRL_NATIVE = 1, /**< SNativeIoControl structure, containing what should be passed to native ioctrl */
IOCTRL_SEEK_POSSIBLE = 2, /**< return 0 if known not to work, 1 if it should work */
IOCTRL_CACHE_STATUS = 3, /**< SCacheStatus structure */
diff --git a/xbmc/games/addons/GameClient.cpp b/xbmc/games/addons/GameClient.cpp
index 6222a8766e..71dbbb646f 100644
--- a/xbmc/games/addons/GameClient.cpp
+++ b/xbmc/games/addons/GameClient.cpp
@@ -113,8 +113,8 @@ CGameClient::~CGameClient(void)
std::string CGameClient::LibPath() const
{
// If the game client requires a proxy, load its DLL instead
- if (m_struct.props.proxy_dll_count > 0)
- return GetDllPath(m_struct.props.proxy_dll_paths[0]);
+ if (m_struct.props->proxy_dll_count > 0)
+ return GetDllPath(m_struct.props->proxy_dll_paths[0]);
return CAddonDll::LibPath();
}
@@ -160,15 +160,17 @@ bool CGameClient::Initialize(void)
if (!AddonProperties().InitializeProperties())
return false;
- m_struct.toKodi.kodiInstance = this;
- m_struct.toKodi.CloseGame = cb_close_game;
- m_struct.toKodi.OpenStream = cb_open_stream;
- m_struct.toKodi.GetStreamBuffer = cb_get_stream_buffer;
- m_struct.toKodi.AddStreamData = cb_add_stream_data;
- m_struct.toKodi.ReleaseStreamBuffer = cb_release_stream_buffer;
- m_struct.toKodi.CloseStream = cb_close_stream;
- m_struct.toKodi.HwGetProcAddress = cb_hw_get_proc_address;
- m_struct.toKodi.InputEvent = cb_input_event;
+ m_struct.toKodi->kodiInstance = this;
+ m_struct.toKodi->CloseGame = cb_close_game;
+ m_struct.toKodi->OpenStream = cb_open_stream;
+ m_struct.toKodi->GetStreamBuffer = cb_get_stream_buffer;
+ m_struct.toKodi->AddStreamData = cb_add_stream_data;
+ m_struct.toKodi->ReleaseStreamBuffer = cb_release_stream_buffer;
+ m_struct.toKodi->CloseStream = cb_close_stream;
+ m_struct.toKodi->HwGetProcAddress = cb_hw_get_proc_address;
+ m_struct.toKodi->InputEvent = cb_input_event;
+
+ memset(m_struct.toAddon, 0, sizeof(KodiToAddonFuncTable_Game));
if (CreateInstance(ADDON_INSTANCE_GAME, this, "", &m_struct, nullptr) == ADDON_STATUS_OK)
{
@@ -229,7 +231,7 @@ bool CGameClient::OpenFile(const CFileItem& file,
try
{
- LogError(error = m_struct.toAddon.LoadGame(&m_struct, path.c_str()), "LoadGame()");
+ LogError(error = m_struct.toAddon->LoadGame(&m_struct, path.c_str()), "LoadGame()");
}
catch (...)
{
@@ -265,7 +267,7 @@ bool CGameClient::OpenStandalone(RETRO::IStreamManager& streamManager, IGameInpu
try
{
- LogError(error = m_struct.toAddon.LoadStandalone(&m_struct), "LoadStandalone()");
+ LogError(error = m_struct.toAddon->LoadStandalone(&m_struct), "LoadStandalone()");
}
catch (...)
{
@@ -313,7 +315,7 @@ bool CGameClient::LoadGameInfo()
bool bRequiresGameLoop;
try
{
- bRequiresGameLoop = m_struct.toAddon.RequiresGameLoop(&m_struct);
+ bRequiresGameLoop = m_struct.toAddon->RequiresGameLoop(&m_struct);
}
catch (...)
{
@@ -328,7 +330,7 @@ bool CGameClient::LoadGameInfo()
bool bSuccess = false;
try
{
- bSuccess = LogError(m_struct.toAddon.GetGameTiming(&m_struct, &timingInfo), "GetGameTiming()");
+ bSuccess = LogError(m_struct.toAddon->GetGameTiming(&m_struct, &timingInfo), "GetGameTiming()");
}
catch (...)
{
@@ -344,7 +346,7 @@ bool CGameClient::LoadGameInfo()
GAME_REGION region;
try
{
- region = m_struct.toAddon.GetRegion(&m_struct);
+ region = m_struct.toAddon->GetRegion(&m_struct);
}
catch (...)
{
@@ -355,7 +357,7 @@ bool CGameClient::LoadGameInfo()
size_t serializeSize;
try
{
- serializeSize = m_struct.toAddon.SerializeSize(&m_struct);
+ serializeSize = m_struct.toAddon->SerializeSize(&m_struct);
}
catch (...)
{
@@ -438,7 +440,7 @@ void CGameClient::Reset()
{
try
{
- LogError(m_struct.toAddon.Reset(&m_struct), "Reset()");
+ LogError(m_struct.toAddon->Reset(&m_struct), "Reset()");
}
catch (...)
{
@@ -465,7 +467,7 @@ void CGameClient::CloseFile()
try
{
- LogError(m_struct.toAddon.UnloadGame(&m_struct), "UnloadGame()");
+ LogError(m_struct.toAddon->UnloadGame(&m_struct), "UnloadGame()");
}
catch (...)
{
@@ -494,7 +496,7 @@ void CGameClient::RunFrame()
{
try
{
- LogError(m_struct.toAddon.RunFrame(&m_struct), "RunFrame()");
+ LogError(m_struct.toAddon->RunFrame(&m_struct), "RunFrame()");
}
catch (...)
{
@@ -515,7 +517,7 @@ bool CGameClient::Serialize(uint8_t* data, size_t size)
{
try
{
- bSuccess = LogError(m_struct.toAddon.Serialize(&m_struct, data, size), "Serialize()");
+ bSuccess = LogError(m_struct.toAddon->Serialize(&m_struct, data, size), "Serialize()");
}
catch (...)
{
@@ -538,7 +540,7 @@ bool CGameClient::Deserialize(const uint8_t* data, size_t size)
{
try
{
- bSuccess = LogError(m_struct.toAddon.Deserialize(&m_struct, data, size), "Deserialize()");
+ bSuccess = LogError(m_struct.toAddon->Deserialize(&m_struct, data, size), "Deserialize()");
}
catch (...)
{
@@ -581,7 +583,7 @@ void CGameClient::LogException(const char* strFunctionName) const
}
-void CGameClient::cb_close_game(void* kodiInstance)
+void CGameClient::cb_close_game(KODI_HANDLE kodiInstance)
{
using namespace MESSAGING;
@@ -589,7 +591,8 @@ void CGameClient::cb_close_game(void* kodiInstance)
static_cast<void*>(new CAction(ACTION_STOP)));
}
-void* CGameClient::cb_open_stream(void* kodiInstance, const game_stream_properties* properties)
+KODI_GAME_STREAM_HANDLE CGameClient::cb_open_stream(KODI_HANDLE kodiInstance,
+ const game_stream_properties* properties)
{
if (properties == nullptr)
return nullptr;
@@ -601,8 +604,8 @@ void* CGameClient::cb_open_stream(void* kodiInstance, const game_stream_properti
return gameClient->Streams().OpenStream(*properties);
}
-bool CGameClient::cb_get_stream_buffer(void* kodiInstance,
- void* stream,
+bool CGameClient::cb_get_stream_buffer(KODI_HANDLE kodiInstance,
+ KODI_GAME_STREAM_HANDLE stream,
unsigned int width,
unsigned int height,
game_stream_buffer* buffer)
@@ -617,8 +620,8 @@ bool CGameClient::cb_get_stream_buffer(void* kodiInstance,
return gameClientStream->GetBuffer(width, height, *buffer);
}
-void CGameClient::cb_add_stream_data(void* kodiInstance,
- void* stream,
+void CGameClient::cb_add_stream_data(KODI_HANDLE kodiInstance,
+ KODI_GAME_STREAM_HANDLE stream,
const game_stream_packet* packet)
{
if (packet == nullptr)
@@ -631,8 +634,8 @@ void CGameClient::cb_add_stream_data(void* kodiInstance,
gameClientStream->AddData(*packet);
}
-void CGameClient::cb_release_stream_buffer(void* kodiInstance,
- void* stream,
+void CGameClient::cb_release_stream_buffer(KODI_HANDLE kodiInstance,
+ KODI_GAME_STREAM_HANDLE stream,
game_stream_buffer* buffer)
{
if (buffer == nullptr)
@@ -645,7 +648,7 @@ void CGameClient::cb_release_stream_buffer(void* kodiInstance,
gameClientStream->ReleaseBuffer(*buffer);
}
-void CGameClient::cb_close_stream(void* kodiInstance, void* stream)
+void CGameClient::cb_close_stream(KODI_HANDLE kodiInstance, KODI_GAME_STREAM_HANDLE stream)
{
CGameClient* gameClient = static_cast<CGameClient*>(kodiInstance);
if (gameClient == nullptr)
@@ -658,7 +661,7 @@ void CGameClient::cb_close_stream(void* kodiInstance, void* stream)
gameClient->Streams().CloseStream(gameClientStream);
}
-game_proc_address_t CGameClient::cb_hw_get_proc_address(void* kodiInstance, const char* sym)
+game_proc_address_t CGameClient::cb_hw_get_proc_address(KODI_HANDLE kodiInstance, const char* sym)
{
CGameClient* gameClient = static_cast<CGameClient*>(kodiInstance);
if (!gameClient)
@@ -668,7 +671,7 @@ game_proc_address_t CGameClient::cb_hw_get_proc_address(void* kodiInstance, cons
return nullptr;
}
-bool CGameClient::cb_input_event(void* kodiInstance, const game_input_event* event)
+bool CGameClient::cb_input_event(KODI_HANDLE kodiInstance, const game_input_event* event)
{
CGameClient* gameClient = static_cast<CGameClient*>(kodiInstance);
if (!gameClient)
diff --git a/xbmc/games/addons/GameClient.h b/xbmc/games/addons/GameClient.h
index 89cea002b8..7e4e47dc84 100644
--- a/xbmc/games/addons/GameClient.h
+++ b/xbmc/games/addons/GameClient.h
@@ -38,6 +38,31 @@ class IGameInputCallback;
/*!
* \ingroup games
+ * \brief Helper class to have "C" struct created before other parts becomes his pointer.
+ */
+class CGameClientStruct
+{
+public:
+ CGameClientStruct()
+ {
+ // Create "C" interface structures, used as own parts to prevent API problems on update
+ m_struct.props = new AddonProps_Game();
+ m_struct.toKodi = new AddonToKodiFuncTable_Game();
+ m_struct.toAddon = new KodiToAddonFuncTable_Game();
+ }
+
+ ~CGameClientStruct()
+ {
+ delete m_struct.toAddon;
+ delete m_struct.toKodi;
+ delete m_struct.props;
+ }
+
+ AddonInstance_Game m_struct;
+};
+
+/*!
+ * \ingroup games
* \brief Interface between Kodi and Game add-ons.
*
* The game add-on system is extremely large. To make the code more manageable,
@@ -65,7 +90,7 @@ class IGameInputCallback;
* from 1,200 lines to just over 600. Reducing this further is the challenge.
* You must now choose whether to accept.
*/
-class CGameClient : public ADDON::CAddonDll
+class CGameClient : public ADDON::CAddonDll, private CGameClientStruct
{
public:
explicit CGameClient(const ADDON::AddonInfoPtr& addonInfo);
@@ -145,22 +170,23 @@ private:
* @brief Callback functions from addon to kodi
*/
//@{
- static void cb_close_game(void* kodiInstance);
- static void* cb_open_stream(void* kodiInstance, const game_stream_properties* properties);
- static bool cb_get_stream_buffer(void* kodiInstance,
- void* stream,
+ static void cb_close_game(KODI_HANDLE kodiInstance);
+ static KODI_GAME_STREAM_HANDLE cb_open_stream(KODI_HANDLE kodiInstance,
+ const game_stream_properties* properties);
+ static bool cb_get_stream_buffer(KODI_HANDLE kodiInstance,
+ KODI_GAME_STREAM_HANDLE stream,
unsigned int width,
unsigned int height,
game_stream_buffer* buffer);
- static void cb_add_stream_data(void* kodiInstance,
- void* stream,
+ static void cb_add_stream_data(KODI_HANDLE kodiInstance,
+ KODI_GAME_STREAM_HANDLE stream,
const game_stream_packet* packet);
- static void cb_release_stream_buffer(void* kodiInstance,
- void* stream,
+ static void cb_release_stream_buffer(KODI_HANDLE kodiInstance,
+ KODI_GAME_STREAM_HANDLE stream,
game_stream_buffer* buffer);
- static void cb_close_stream(void* kodiInstance, void* stream);
- static game_proc_address_t cb_hw_get_proc_address(void* kodiInstance, const char* sym);
- static bool cb_input_event(void* kodiInstance, const game_input_event* event);
+ static void cb_close_stream(KODI_HANDLE kodiInstance, KODI_GAME_STREAM_HANDLE stream);
+ static game_proc_address_t cb_hw_get_proc_address(KODI_HANDLE kodiInstance, const char* sym);
+ static bool cb_input_event(KODI_HANDLE kodiInstance, const game_input_event* event);
//@}
// Game subsystems
@@ -187,8 +213,6 @@ private:
std::unique_ptr<CGameClientInGameSaves> m_inGameSaves;
CCriticalSection m_critSection;
-
- AddonInstance_Game m_struct;
};
} // namespace GAME
diff --git a/xbmc/games/addons/GameClientInGameSaves.cpp b/xbmc/games/addons/GameClientInGameSaves.cpp
index 7989173f01..30291a76ee 100644
--- a/xbmc/games/addons/GameClientInGameSaves.cpp
+++ b/xbmc/games/addons/GameClientInGameSaves.cpp
@@ -78,7 +78,7 @@ void CGameClientInGameSaves::Load(GAME_MEMORY memoryType)
try
{
- m_dllStruct->toAddon.GetMemory(m_dllStruct, memoryType, &gameMemory, &size);
+ m_dllStruct->toAddon->GetMemory(m_dllStruct, memoryType, &gameMemory, &size);
}
catch (...)
{
@@ -123,7 +123,7 @@ void CGameClientInGameSaves::Save(GAME_MEMORY memoryType)
try
{
- m_dllStruct->toAddon.GetMemory(m_dllStruct, memoryType, &gameMemory, &size);
+ m_dllStruct->toAddon->GetMemory(m_dllStruct, memoryType, &gameMemory, &size);
}
catch (...)
{
diff --git a/xbmc/games/addons/GameClientSubsystem.cpp b/xbmc/games/addons/GameClientSubsystem.cpp
index 7fc47a2efa..d3ed56878b 100644
--- a/xbmc/games/addons/GameClientSubsystem.cpp
+++ b/xbmc/games/addons/GameClientSubsystem.cpp
@@ -33,7 +33,7 @@ GameClientSubsystems CGameClientSubsystem::CreateSubsystems(CGameClient& gameCli
GameClientSubsystems subsystems = {};
subsystems.Input.reset(new CGameClientInput(gameClient, gameStruct, clientAccess));
- subsystems.AddonProperties.reset(new CGameClientProperties(gameClient, gameStruct.props));
+ subsystems.AddonProperties.reset(new CGameClientProperties(gameClient, *gameStruct.props));
subsystems.Streams.reset(new CGameClientStreams(gameClient));
return subsystems;
diff --git a/xbmc/games/addons/input/GameClientInput.cpp b/xbmc/games/addons/input/GameClientInput.cpp
index 515b2fa916..485f97409e 100644
--- a/xbmc/games/addons/input/GameClientInput.cpp
+++ b/xbmc/games/addons/input/GameClientInput.cpp
@@ -137,7 +137,8 @@ bool CGameClientInput::HasFeature(const std::string& controllerId,
try
{
- bHasFeature = m_struct.toAddon.HasFeature(&m_struct, controllerId.c_str(), featureName.c_str());
+ bHasFeature =
+ m_struct.toAddon->HasFeature(&m_struct, controllerId.c_str(), featureName.c_str());
}
catch (...)
{
@@ -164,7 +165,7 @@ bool CGameClientInput::InputEvent(const game_input_event& event)
try
{
- bHandled = m_struct.toAddon.InputEvent(&m_struct, &event);
+ bHandled = m_struct.toAddon->InputEvent(&m_struct, &event);
}
catch (...)
{
@@ -182,7 +183,7 @@ void CGameClientInput::LoadTopology()
{
try
{
- topologyStruct = m_struct.toAddon.GetTopology(&m_struct);
+ topologyStruct = m_struct.toAddon->GetTopology(&m_struct);
}
catch (...)
{
@@ -208,7 +209,7 @@ void CGameClientInput::LoadTopology()
try
{
- m_struct.toAddon.FreeTopology(&m_struct, topologyStruct);
+ m_struct.toAddon->FreeTopology(&m_struct, topologyStruct);
}
catch (...)
{
@@ -252,8 +253,8 @@ void CGameClientInput::SetControllerLayouts(const ControllerVector& controllers)
try
{
- m_struct.toAddon.SetControllerLayouts(&m_struct, controllerStructs.data(),
- static_cast<unsigned int>(controllerStructs.size()));
+ m_struct.toAddon->SetControllerLayouts(&m_struct, controllerStructs.data(),
+ static_cast<unsigned int>(controllerStructs.size()));
}
catch (...)
{
@@ -334,7 +335,7 @@ bool CGameClientInput::OpenKeyboard(const ControllerPtr& controller)
{
try
{
- bSuccess = m_struct.toAddon.EnableKeyboard(&m_struct, true, controller->ID().c_str());
+ bSuccess = m_struct.toAddon->EnableKeyboard(&m_struct, true, controller->ID().c_str());
}
catch (...)
{
@@ -364,7 +365,7 @@ void CGameClientInput::CloseKeyboard()
{
try
{
- m_struct.toAddon.EnableKeyboard(&m_struct, false, "");
+ m_struct.toAddon->EnableKeyboard(&m_struct, false, "");
}
catch (...)
{
@@ -399,7 +400,7 @@ bool CGameClientInput::OpenMouse(const ControllerPtr& controller)
{
try
{
- bSuccess = m_struct.toAddon.EnableMouse(&m_struct, true, controller->ID().c_str());
+ bSuccess = m_struct.toAddon->EnableMouse(&m_struct, true, controller->ID().c_str());
}
catch (...)
{
@@ -428,7 +429,7 @@ void CGameClientInput::CloseMouse()
{
try
{
- m_struct.toAddon.EnableMouse(&m_struct, false, "");
+ m_struct.toAddon->EnableMouse(&m_struct, false, "");
}
catch (...)
{
@@ -467,8 +468,8 @@ bool CGameClientInput::OpenJoystick(const std::string& portAddress, const Contro
{
try
{
- bSuccess = m_struct.toAddon.ConnectController(&m_struct, true, portAddress.c_str(),
- controller->ID().c_str());
+ bSuccess = m_struct.toAddon->ConnectController(&m_struct, true, portAddress.c_str(),
+ controller->ID().c_str());
}
catch (...)
{
@@ -512,7 +513,7 @@ void CGameClientInput::CloseJoystick(const std::string& portAddress)
{
try
{
- m_struct.toAddon.ConnectController(&m_struct, false, portAddress.c_str(), "");
+ m_struct.toAddon->ConnectController(&m_struct, false, portAddress.c_str(), "");
}
catch (...)
{
diff --git a/xbmc/guilib/CMakeLists.txt b/xbmc/guilib/CMakeLists.txt
index 9adceca14c..f64e112d3e 100644
--- a/xbmc/guilib/CMakeLists.txt
+++ b/xbmc/guilib/CMakeLists.txt
@@ -177,11 +177,6 @@ if(OPENGLES_FOUND)
TextureGL.h)
endif()
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- list(APPEND SOURCES TexturePi.cpp)
- list(APPEND HEADERS TexturePi.h)
-endif()
-
if(CORE_SYSTEM_NAME STREQUAL windows OR CORE_SYSTEM_NAME STREQUAL windowsstore)
list(APPEND SOURCES D3DResource.cpp
DirectXGraphics.cpp
diff --git a/xbmc/guilib/Texture.h b/xbmc/guilib/Texture.h
index b33847cadb..084a48bc31 100644
--- a/xbmc/guilib/Texture.h
+++ b/xbmc/guilib/Texture.h
@@ -133,10 +133,7 @@ protected:
bool m_bCacheMemory = false;
};
-#if defined(TARGET_RASPBERRY_PI)
-#include "TexturePi.h"
-#define CTexture CPiTexture
-#elif defined(HAS_GL) || defined(HAS_GLES)
+#if defined(HAS_GL) || defined(HAS_GLES)
#include "TextureGL.h"
#define CTexture CGLTexture
#elif defined(HAS_DX)
diff --git a/xbmc/guilib/TexturePi.cpp b/xbmc/guilib/TexturePi.cpp
deleted file mode 100644
index dc7ebdd5c7..0000000000
--- a/xbmc/guilib/TexturePi.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2013-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "Texture.h"
-#include "cores/omxplayer/OMXImage.h"
-#include "guilib/TextureManager.h"
-#include "utils/GLUtils.h"
-#include "utils/URIUtils.h"
-#include "utils/log.h"
-
-/************************************************************************/
-/* CPiTexture */
-/************************************************************************/
-
-CPiTexture::CPiTexture(unsigned int width, unsigned int height, unsigned int format)
-: CGLTexture(width, height, format)
-{
- m_egl_image = NULL;
-}
-
-CPiTexture::~CPiTexture()
-{
- if (m_egl_image)
- {
- g_OMXImage.DestroyTexture(m_egl_image);
- m_egl_image = NULL;
- }
-}
-
-void CPiTexture::Allocate(unsigned int width, unsigned int height, unsigned int format)
-{
- if (m_egl_image)
- {
- m_imageWidth = m_originalWidth = width;
- m_imageHeight = m_originalHeight = height;
- m_format = format;
- m_orientation = 0;
-
- m_textureWidth = m_imageWidth;
- m_textureHeight = m_imageHeight;
- return;
- }
- return CGLTexture::Allocate(width, height, format);
-}
-
-void CPiTexture::CreateTextureObject()
-{
- if (m_egl_image && !m_texture)
- {
- g_OMXImage.GetTexture(m_egl_image, &m_texture);
- return;
- }
- CGLTexture::CreateTextureObject();
-}
-
-void CPiTexture::LoadToGPU()
-{
- if (m_egl_image)
- {
- if (m_loadedToGPU)
- {
- // nothing to load - probably same image (no change)
- return;
- }
- if (m_texture == 0)
- {
- // Have OpenGL generate a texture object handle for us
- // this happens only one time - the first time the texture is loaded
- CreateTextureObject();
- }
-
- // Bind the texture object
- glBindTexture(GL_TEXTURE_2D, m_texture);
-
- if (IsMipmapped()) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- m_loadedToGPU = true;
- return;
- }
- CGLTexture::LoadToGPU();
-}
-
-void CPiTexture::Update(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, const unsigned char *pixels, bool loadToGPU)
-{
- if (m_egl_image)
- {
- if (loadToGPU)
- LoadToGPU();
- return;
- }
- CGLTexture::Update(width, height, pitch, format, pixels, loadToGPU);
-}
-
-bool CPiTexture::LoadFromFileInternal(const std::string& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool requirePixels, const std::string& strMimeType)
-{
- if (URIUtils::HasExtension(texturePath, ".jpg|.tbn"))
- {
- COMXImageFile *file = g_OMXImage.LoadJpeg(texturePath);
- if (file)
- {
- bool okay = false;
- int orientation = file->GetOrientation();
- // limit the sizes of jpegs (even if we fail to decode)
- g_OMXImage.ClampLimits(maxWidth, maxHeight, file->GetWidth(), file->GetHeight(), orientation & 4);
-
- if (requirePixels)
- {
- Allocate(maxWidth, maxHeight, XB_FMT_A8R8G8B8);
- if (m_pixels && COMXImage::DecodeJpeg(file, maxWidth, GetRows(), GetPitch(), (void *)m_pixels))
- okay = true;
- }
- else
- {
- if (g_OMXImage.DecodeJpegToTexture(file, maxWidth, maxHeight, &m_egl_image) && m_egl_image)
- {
- Allocate(maxWidth, maxHeight, XB_FMT_A8R8G8B8);
- okay = true;
- }
- }
- g_OMXImage.CloseJpeg(file);
- if (okay)
- {
- m_hasAlpha = false;
- m_orientation = orientation;
- return true;
- }
- }
- }
- return CGLTexture::LoadFromFileInternal(texturePath, maxWidth, maxHeight, requirePixels);
-}
diff --git a/xbmc/guilib/TexturePi.h b/xbmc/guilib/TexturePi.h
deleted file mode 100644
index 96ac178474..0000000000
--- a/xbmc/guilib/TexturePi.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013-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 "TextureGL.h"
-
-#include "system_gl.h"
-
-/************************************************************************/
-/* CGLTexture */
-/************************************************************************/
-class CPiTexture : public CGLTexture
-{
-public:
- CPiTexture(unsigned int width = 0, unsigned int height = 0, unsigned int format = XB_FMT_A8R8G8B8);
- virtual ~CPiTexture();
- void CreateTextureObject();
- void LoadToGPU();
- void Update(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, const unsigned char *pixels, bool loadToGPU);
- void Allocate(unsigned int width, unsigned int height, unsigned int format);
- bool LoadFromFileInternal(const std::string& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool requirePixels, const std::string& strMimeType = "");
-
-protected:
-
-private:
- void *m_egl_image;
-};
diff --git a/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp b/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
index c3a4f70083..c1dcaf322a 100644
--- a/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
@@ -56,7 +56,34 @@ bool CAddonsGUIInfo::GetLabel(std::string& value, const CFileItem *item, int con
value = addonInfo->ChangeLog();
return true;
case LISTITEM_ADDON_BROKEN:
- value = addonInfo->Broken();
+ {
+ // Fallback for old GUI info
+ if (addonInfo->LifecycleState() == ADDON::AddonLifecycleState::BROKEN)
+ value = addonInfo->LifecycleStateDescription();
+ else
+ value = "";
+ return true;
+ }
+ case LISTITEM_ADDON_LIFECYCLE_TYPE:
+ {
+ const ADDON::AddonLifecycleState state = addonInfo->LifecycleState();
+ switch (state)
+ {
+ case ADDON::AddonLifecycleState::BROKEN:
+ value = g_localizeStrings.Get(24171); // "Broken"
+ break;
+ case ADDON::AddonLifecycleState::DEPRECATED:
+ value = g_localizeStrings.Get(24170); // "Deprecated";
+ break;
+ case ADDON::AddonLifecycleState::NORMAL:
+ default:
+ value = g_localizeStrings.Get(24169); // "Normal";
+ break;
+ }
+ return true;
+ }
+ case LISTITEM_ADDON_LIFECYCLE_DESC:
+ value = addonInfo->LifecycleStateDescription();
return true;
case LISTITEM_ADDON_TYPE:
value = ADDON::CAddonInfo::TranslateType(addonInfo->Type(), true);
@@ -181,6 +208,14 @@ bool CAddonsGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int context
value = !CServiceBroker::GetAddonMgr().IsAddonDisabled(info.GetData3());
return true;
}
+ case LISTITEM_ISAUTOUPDATEABLE:
+ {
+ value = true;
+ const CFileItem* item = static_cast<const CFileItem*>(gitem);
+ if (item->GetAddonInfo())
+ value = CServiceBroker::GetAddonMgr().IsAutoUpdateable(item->GetAddonInfo()->ID());
+ return true;
+ }
}
return false;
diff --git a/xbmc/guilib/guiinfo/GUIControlsGUIInfo.cpp b/xbmc/guilib/guiinfo/GUIControlsGUIInfo.cpp
index 7d436dd1af..5cca36338a 100644
--- a/xbmc/guilib/guiinfo/GUIControlsGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/GUIControlsGUIInfo.cpp
@@ -495,7 +495,7 @@ bool CGUIControlsGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int co
const CGUIViewState *viewState = window->GetViewState();
if (viewState)
{
- value = (static_cast<unsigned int>(viewState->GetSortMethod().sortBy) == info.GetData2());
+ value = (static_cast<int>(viewState->GetSortMethod().sortBy) == info.GetData2());
return true;
}
}
diff --git a/xbmc/guilib/guiinfo/GUIInfoLabels.h b/xbmc/guilib/guiinfo/GUIInfoLabels.h
index 683476e604..2709c5ecc1 100644
--- a/xbmc/guilib/guiinfo/GUIInfoLabels.h
+++ b/xbmc/guilib/guiinfo/GUIInfoLabels.h
@@ -49,17 +49,17 @@
#define PLAYER_SUBTITLE_DELAY 42
#define PLAYER_AUDIO_DELAY 43
#define PLAYER_PASSTHROUGH 44
-#define PLAYER_PATH 45
-#define PLAYER_FILEPATH 46
+// unused 45
+// unused 46
#define PLAYER_SEEKOFFSET 47
#define PLAYER_PROGRESS_CACHE 48
#define PLAYER_ITEM_ART 49
#define PLAYER_CAN_PAUSE 50
#define PLAYER_CAN_SEEK 51
#define PLAYER_START_TIME 52
-#define PLAYER_TITLE 53
+// unused 53
#define PLAYER_ISINTERNETSTREAM 54
-#define PLAYER_FILENAME 55
+// unused 55
#define PLAYER_SEEKSTEPSIZE 56
#define PLAYER_IS_CHANNEL_PREVIEW_ACTIVE 57
#define PLAYER_SUPPORTS_TEMPO 58
@@ -73,6 +73,15 @@
#define PLAYER_ICON 66
#define PLAYER_CUTLIST 67
#define PLAYER_CHAPTERS 68
+// Keep player infolabels that work with offset and position together
+#define PLAYER_PATH 81
+#define PLAYER_FILEPATH 82
+#define PLAYER_TITLE 83
+#define PLAYER_FILENAME 84
+
+// Range of player infolabels that work with offset and position
+#define PLAYER_OFFSET_POSITION_FIRST PLAYER_PATH
+#define PLAYER_OFFSET_POSITION_LAST PLAYER_FILENAME
#define WEATHER_CONDITIONS_TEXT 100
#define WEATHER_TEMPERATURE 101
@@ -198,12 +207,14 @@
#define MUSICPLAYER_CHANNEL_NAME 237
#define MUSICPLAYER_CHANNEL_GROUP 238
#define MUSICPLAYER_CHANNEL_NUMBER 239
+#define MUSICPLAYER_TOTALDISCS 240
// Musicplayer infobools
-#define MUSICPLAYER_HASPREVIOUS 240
-#define MUSICPLAYER_HASNEXT 241
-#define MUSICPLAYER_EXISTS 242
-#define MUSICPLAYER_PLAYLISTPLAYING 243
-#define MUSICPLAYER_CONTENT 244
+#define MUSICPLAYER_HASPREVIOUS 241
+#define MUSICPLAYER_HASNEXT 242
+#define MUSICPLAYER_EXISTS 243
+#define MUSICPLAYER_PLAYLISTPLAYING 244
+#define MUSICPLAYER_CONTENT 245
+#define MUSICPLAYER_ISMULTIDISC 246
// Keep videoplayer infolabels that work with offset and position together
#define VIDEOPLAYER_TITLE 250
@@ -443,7 +454,7 @@
#define SYSTEM_PLATFORM_DARWIN_IOS 745
#define SYSTEM_PLATFORM_UWP 746
#define SYSTEM_PLATFORM_ANDROID 747
-#define SYSTEM_PLATFORM_LINUX_RASPBERRY_PI 748
+// previously used by rpi 748
#define SYSTEM_PLATFORM_WIN10 749
#define SYSTEM_CAN_POWERDOWN 750
@@ -887,40 +898,43 @@
#define LISTITEM_ADDON_DESCRIPTION (LISTITEM_START + 168)
#define LISTITEM_ADDON_DISCLAIMER (LISTITEM_START + 169)
#define LISTITEM_ADDON_BROKEN (LISTITEM_START + 170)
-#define LISTITEM_ADDON_TYPE (LISTITEM_START + 171)
-#define LISTITEM_ADDON_INSTALL_DATE (LISTITEM_START + 172)
-#define LISTITEM_ADDON_LAST_UPDATED (LISTITEM_START + 173)
-#define LISTITEM_ADDON_LAST_USED (LISTITEM_START + 174)
-#define LISTITEM_STATUS (LISTITEM_START + 175)
-#define LISTITEM_ENDTIME_RESUME (LISTITEM_START + 176)
-#define LISTITEM_ADDON_ORIGIN (LISTITEM_START + 177)
-#define LISTITEM_ADDON_NEWS (LISTITEM_START + 178)
-#define LISTITEM_ADDON_SIZE (LISTITEM_START + 179)
-#define LISTITEM_EXPIRATION_DATE (LISTITEM_START + 180)
-#define LISTITEM_EXPIRATION_TIME (LISTITEM_START + 181)
-#define LISTITEM_PROPERTY (LISTITEM_START + 182)
-#define LISTITEM_EPG_EVENT_ICON (LISTITEM_START + 183)
-#define LISTITEM_HASREMINDERRULE (LISTITEM_START + 184)
-#define LISTITEM_HASARCHIVE (LISTITEM_START + 185)
-#define LISTITEM_ISPLAYABLE (LISTITEM_START + 186)
-#define LISTITEM_FILENAME_NO_EXTENSION (LISTITEM_START + 187)
-#define LISTITEM_CURRENTITEM (LISTITEM_START + 188)
-#define LISTITEM_IS_NEW (LISTITEM_START + 189)
-#define LISTITEM_DISC_TITLE (LISTITEM_START + 190)
-#define LISTITEM_IS_BOXSET (LISTITEM_START + 191)
-#define LISTITEM_TOTALDISCS (LISTITEM_START + 192)
-#define LISTITEM_RELEASEDATE (LISTITEM_START + 193)
-#define LISTITEM_ORIGINALDATE (LISTITEM_START + 194)
-#define LISTITEM_BPM (LISTITEM_START + 195)
-#define LISTITEM_UNIQUEID (LISTITEM_START + 196)
-#define LISTITEM_BITRATE (LISTITEM_START + 197)
-#define LISTITEM_SAMPLERATE (LISTITEM_START + 198)
-#define LISTITEM_MUSICCHANNELS (LISTITEM_START + 199)
-#define LISTITEM_IS_PREMIERE (LISTITEM_START + 200)
-#define LISTITEM_IS_FINALE (LISTITEM_START + 201)
-#define LISTITEM_IS_LIVE (LISTITEM_START + 202)
-#define LISTITEM_TVSHOWDBID (LISTITEM_START + 203)
-#define LISTITEM_ALBUMSTATUS (LISTITEM_START + 204)
+#define LISTITEM_ADDON_LIFECYCLE_TYPE (LISTITEM_START + 171)
+#define LISTITEM_ADDON_LIFECYCLE_DESC (LISTITEM_START + 172)
+#define LISTITEM_ADDON_TYPE (LISTITEM_START + 173)
+#define LISTITEM_ADDON_INSTALL_DATE (LISTITEM_START + 174)
+#define LISTITEM_ADDON_LAST_UPDATED (LISTITEM_START + 175)
+#define LISTITEM_ADDON_LAST_USED (LISTITEM_START + 176)
+#define LISTITEM_STATUS (LISTITEM_START + 177)
+#define LISTITEM_ENDTIME_RESUME (LISTITEM_START + 178)
+#define LISTITEM_ADDON_ORIGIN (LISTITEM_START + 179)
+#define LISTITEM_ADDON_NEWS (LISTITEM_START + 180)
+#define LISTITEM_ADDON_SIZE (LISTITEM_START + 181)
+#define LISTITEM_EXPIRATION_DATE (LISTITEM_START + 182)
+#define LISTITEM_EXPIRATION_TIME (LISTITEM_START + 183)
+#define LISTITEM_PROPERTY (LISTITEM_START + 184)
+#define LISTITEM_EPG_EVENT_ICON (LISTITEM_START + 185)
+#define LISTITEM_HASREMINDERRULE (LISTITEM_START + 186)
+#define LISTITEM_HASARCHIVE (LISTITEM_START + 187)
+#define LISTITEM_ISPLAYABLE (LISTITEM_START + 188)
+#define LISTITEM_FILENAME_NO_EXTENSION (LISTITEM_START + 189)
+#define LISTITEM_CURRENTITEM (LISTITEM_START + 190)
+#define LISTITEM_IS_NEW (LISTITEM_START + 191)
+#define LISTITEM_DISC_TITLE (LISTITEM_START + 192)
+#define LISTITEM_IS_BOXSET (LISTITEM_START + 193)
+#define LISTITEM_TOTALDISCS (LISTITEM_START + 194)
+#define LISTITEM_RELEASEDATE (LISTITEM_START + 195)
+#define LISTITEM_ORIGINALDATE (LISTITEM_START + 196)
+#define LISTITEM_BPM (LISTITEM_START + 197)
+#define LISTITEM_UNIQUEID (LISTITEM_START + 198)
+#define LISTITEM_BITRATE (LISTITEM_START + 199)
+#define LISTITEM_SAMPLERATE (LISTITEM_START + 200)
+#define LISTITEM_MUSICCHANNELS (LISTITEM_START + 201)
+#define LISTITEM_IS_PREMIERE (LISTITEM_START + 202)
+#define LISTITEM_IS_FINALE (LISTITEM_START + 203)
+#define LISTITEM_IS_LIVE (LISTITEM_START + 204)
+#define LISTITEM_TVSHOWDBID (LISTITEM_START + 205)
+#define LISTITEM_ALBUMSTATUS (LISTITEM_START + 206)
+#define LISTITEM_ISAUTOUPDATEABLE (LISTITEM_START + 207)
#define LISTITEM_END (LISTITEM_START + 2500)
diff --git a/xbmc/guilib/guiinfo/MusicGUIInfo.cpp b/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
index 57cfe92970..babf96342d 100644
--- a/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
@@ -77,8 +77,9 @@ bool CMusicGUIInfo::InitCurrentItem(CFileItem *item)
bool CMusicGUIInfo::GetLabel(std::string& value, const CFileItem *item, int contextWindow, const CGUIInfo &info, std::string *fallback) const
{
// For musicplayer "offset" and "position" info labels check playlist
- if (info.GetData1() && info.m_info >= MUSICPLAYER_OFFSET_POSITION_FIRST &&
- info.m_info <= MUSICPLAYER_OFFSET_POSITION_LAST)
+ if (info.GetData1() && ((info.m_info >= MUSICPLAYER_OFFSET_POSITION_FIRST &&
+ info.m_info <= MUSICPLAYER_OFFSET_POSITION_LAST) ||
+ (info.m_info >= PLAYER_OFFSET_POSITION_FIRST && info.m_info <= PLAYER_OFFSET_POSITION_LAST)))
return GetPlaylistInfo(value, info);
const CMusicInfoTag* tag = item->GetMusicInfoTag();
@@ -145,6 +146,7 @@ bool CMusicGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
}
break;
+ case MUSICPLAYER_TOTALDISCS:
case LISTITEM_TOTALDISCS:
value = StringUtils::Format("%i", tag->GetTotalDiscs());
return true;
@@ -573,6 +575,9 @@ bool CMusicGUIInfo::GetInt(int& value, const CGUIListItem *gitem, int contextWin
bool CMusicGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int contextWindow, const CGUIInfo &info) const
{
+ const CFileItem* item = static_cast<const CFileItem*>(gitem);
+ const CMusicInfoTag* tag = item->GetMusicInfoTag();
+
switch (info.m_info)
{
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -619,7 +624,13 @@ bool CMusicGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int contextW
value = (index >= 0 && index < CServiceBroker::GetPlaylistPlayer().GetPlaylist(PLAYLIST_MUSIC).size());
return true;
}
-
+ case MUSICPLAYER_ISMULTIDISC:
+ if (tag)
+ {
+ value = (item->GetMusicInfoTag()->GetTotalDiscs() > 1);
+ return true;
+ }
+ break;
///////////////////////////////////////////////////////////////////////////////////////////////
// MUSICPM_*
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -631,8 +642,6 @@ bool CMusicGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int contextW
// LISTITEM_*
///////////////////////////////////////////////////////////////////////////////////////////////
case LISTITEM_IS_BOXSET:
- const CFileItem* item = static_cast<const CFileItem*>(gitem);
- const CMusicInfoTag* tag = item->GetMusicInfoTag();
if (tag)
{
value = item->GetMusicInfoTag()->GetBoxset() == true;
diff --git a/xbmc/guilib/guiinfo/SystemGUIInfo.cpp b/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
index 8fbe6fefe2..0e1327d683 100644
--- a/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
@@ -492,13 +492,6 @@ bool CSystemGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int context
value = false;
#endif
return true;
- case SYSTEM_PLATFORM_LINUX_RASPBERRY_PI:
-#if defined(TARGET_RASPBERRY_PI)
- value = true;
-#else
- value = false;
-#endif
- return true;
case SYSTEM_MEDIA_DVD:
value = CServiceBroker::GetMediaManager().IsDiscInDrive();
return true;
diff --git a/xbmc/guilib/guiinfo/VideoGUIInfo.cpp b/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
index d34cfac0ab..80a69a2eb7 100644
--- a/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
@@ -87,8 +87,9 @@ bool CVideoGUIInfo::InitCurrentItem(CFileItem *item)
bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int contextWindow, const CGUIInfo &info, std::string *fallback) const
{
// For videoplayer "offset" and "position" info labels check playlist
- if (info.GetData1() && info.m_info >= VIDEOPLAYER_OFFSET_POSITION_FIRST &&
- info.m_info <= VIDEOPLAYER_OFFSET_POSITION_LAST)
+ if (info.GetData1() && ((info.m_info >= VIDEOPLAYER_OFFSET_POSITION_FIRST &&
+ info.m_info <= VIDEOPLAYER_OFFSET_POSITION_LAST) ||
+ (info.m_info >= PLAYER_OFFSET_POSITION_FIRST && info.m_info <= PLAYER_OFFSET_POSITION_LAST)))
return GetPlaylistInfo(value, info);
const CVideoInfoTag* tag = item->GetVideoInfoTag();
diff --git a/xbmc/input/InputManager.cpp b/xbmc/input/InputManager.cpp
index 49c9b9f7c9..298b7958ad 100644
--- a/xbmc/input/InputManager.cpp
+++ b/xbmc/input/InputManager.cpp
@@ -239,7 +239,6 @@ bool CInputManager::ProcessEventServer(int windowId, float frameTime)
if (wKeyID & ES_FLAG_UNICODE)
{
key = CKey(0u, 0u, static_cast<wchar_t>(wKeyID & ~ES_FLAG_UNICODE), 0, 0, 0, 0);
- key.SetFromService(true);
return OnKey(key);
}
diff --git a/xbmc/input/actions/ActionIDs.h b/xbmc/input/actions/ActionIDs.h
index 760228d30a..fe1b565cc5 100644
--- a/xbmc/input/actions/ActionIDs.h
+++ b/xbmc/input/actions/ActionIDs.h
@@ -55,7 +55,6 @@
25 //!< turn subtitles on/off. Can b used in videoFullScreen.xml window id=2005
#define ACTION_NEXT_SUBTITLE \
26 //!< switch to next subtitle of movie. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_BROWSE_SUBTITLE 247 //!< Browse for subtitle. Can be used in videofullscreen
#define ACTION_PLAYER_DEBUG 27 //!< show debug info for VideoPlayer
#define ACTION_NEXT_PICTURE \
28 //!< show next picture of slideshow. Can b used in slideshow.xml window id=2007
@@ -327,7 +326,7 @@
#define ACTION_VOLUME_SET 245
#define ACTION_TOGGLE_COMMSKIP 246
-#define ACTION_HDR_TOGGLE 247 //!< Toggle display HDR on/off
+#define ACTION_BROWSE_SUBTITLE 247 //!< Browse for subtitle. Can be used in videofullscreen
#define ACTION_PLAYER_RESET 248 //!< Send a reset command to the active game
@@ -336,6 +335,8 @@
#define ACTION_VIDEO_NEXT_STREAM 250 //!< Cycle video streams. Used in videofullscreen.
#define ACTION_QUEUE_ITEM_NEXT 251 //!< used to queue an item to the next position in the playlist
+#define ACTION_HDR_TOGGLE 260 //!< Toggle display HDR on/off
+
// Voice actions
#define ACTION_VOICE_RECOGNIZE 300
diff --git a/xbmc/interfaces/json-rpc/AddonsOperations.cpp b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
index 9ac5e164d3..dff6317ef9 100644
--- a/xbmc/interfaces/json-rpc/AddonsOperations.cpp
+++ b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
@@ -247,10 +247,14 @@ static CVariant Serialize(const AddonPtr& addon)
info["optional"] = dep.optional;
variant["dependencies"].push_back(std::move(info));
}
- if (!addon->IsBroken())
+ if (addon->LifecycleState() == AddonLifecycleState::BROKEN)
+ variant["broken"] = addon->LifecycleStateDescription();
+ else
variant["broken"] = false;
+ if (addon->LifecycleState() == AddonLifecycleState::DEPRECATED)
+ variant["deprecated"] = addon->LifecycleStateDescription();
else
- variant["broken"] = addon->Broken();
+ variant["deprecated"] = false;
variant["extrainfo"] = CVariant(CVariant::VariantTypeArray);
for (const auto& kv : addon->ExtraInfo())
{
diff --git a/xbmc/interfaces/json-rpc/schema/types.json b/xbmc/interfaces/json-rpc/schema/types.json
index 8e49251da2..0863c002f2 100644
--- a/xbmc/interfaces/json-rpc/schema/types.json
+++ b/xbmc/interfaces/json-rpc/schema/types.json
@@ -1622,7 +1622,7 @@
"extends": "Item.Fields.Base",
"items": { "type": "string",
"enum": [ "name", "version", "summary", "description", "path", "author", "thumbnail", "disclaimer", "fanart",
- "dependencies", "broken", "extrainfo", "rating", "enabled", "installed" ]
+ "dependencies", "broken", "extrainfo", "rating", "enabled", "installed", "deprecated" ]
}
},
"Addon.Details": {
@@ -1659,7 +1659,8 @@
},
"rating": { "type": "integer" },
"enabled": { "type": "boolean" },
- "installed": { "type": "boolean" }
+ "installed": { "type": "boolean" },
+ "deprecated": { "type": [ "boolean", "string" ] }
}
},
"GUI.Stereoscopy.Mode": {
diff --git a/xbmc/interfaces/json-rpc/schema/version.txt b/xbmc/interfaces/json-rpc/schema/version.txt
index 56b242e498..19b4e985c7 100644
--- a/xbmc/interfaces/json-rpc/schema/version.txt
+++ b/xbmc/interfaces/json-rpc/schema/version.txt
@@ -1 +1 @@
-JSONRPC_VERSION 11.13.0 \ No newline at end of file
+JSONRPC_VERSION 11.14.0
diff --git a/xbmc/interfaces/legacy/ListItem.h b/xbmc/interfaces/legacy/ListItem.h
index 6d030c9c55..9255c09cef 100644
--- a/xbmc/interfaces/legacy/ListItem.h
+++ b/xbmc/interfaces/legacy/ListItem.h
@@ -842,7 +842,7 @@ namespace XBMCAddon
/// **Example:**
/// ~~~~~~~~~~~~~{.py}
/// ...
- /// listitem.addContextMenuItems([('Theater Showtimes', 'RunScript(special://home/scripts/showtimes/default.py,Iron Man)')])
+ /// listitem.addContextMenuItems([('Theater Showtimes', 'RunScript(script.myaddon,title=Iron Man)')])
/// ...
/// ~~~~~~~~~~~~~
///
@@ -868,6 +868,17 @@ namespace XBMCAddon
/// 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 'WatchedCount' for tvshow items
///
+ /// - **Internal Properties**
+ /// | Key | Description |
+ /// |--------------:|:------------------------------------------------|
+ /// | inputstream | string (inputstream.adaptive) - Set the inputstream add-on that will be used to play the item
+ /// | IsPlayable | string - "true", "false" - Mark the item as playable, **mandatory for playable items**
+ /// | MimeType | string (application/x-mpegURL) - Set the MimeType of the item before playback
+ /// | ResumeTime | float (1962.0) - Set the resume point of the item in seconds
+ /// | SpecialSort | string - "top", "bottom" - The item will remain at the top or bottom of the current list
+ /// | StartOffset | float (60.0) - Set the offset in seconds at which to start playback of the item
+ /// | StartPercent | float (15.0) - Set the percentage at which to start playback of the item
+ /// | TotalTime | float (7848.0) - Set the total time of the item in seconds
///
///-----------------------------------------------------------------------
///
diff --git a/xbmc/interfaces/legacy/ModuleXbmc.cpp b/xbmc/interfaces/legacy/ModuleXbmc.cpp
index 0615e832d2..45cc7b7226 100644
--- a/xbmc/interfaces/legacy/ModuleXbmc.cpp
+++ b/xbmc/interfaces/legacy/ModuleXbmc.cpp
@@ -545,10 +545,8 @@ namespace XBMCAddon
int getTRAY_CLOSED_MEDIA_PRESENT() { return TRAY_CLOSED_MEDIA_PRESENT; }
int getLOGDEBUG() { return LOGDEBUG; }
int getLOGINFO() { return LOGINFO; }
- int getLOGNOTICE() { return LOGNOTICE; }
int getLOGWARNING() { return LOGWARNING; }
int getLOGERROR() { return LOGERROR; }
- int getLOGSEVERE() { return LOGSEVERE; }
int getLOGFATAL() { return LOGFATAL; }
int getLOGNONE() { return LOGNONE; }
diff --git a/xbmc/interfaces/legacy/ModuleXbmc.h b/xbmc/interfaces/legacy/ModuleXbmc.h
index 38e92367cf..625cbace3c 100644
--- a/xbmc/interfaces/legacy/ModuleXbmc.h
+++ b/xbmc/interfaces/legacy/ModuleXbmc.h
@@ -907,10 +907,8 @@ namespace XBMCAddon
SWIG_CONSTANT_FROM_GETTER(int, TRAY_CLOSED_MEDIA_PRESENT);
SWIG_CONSTANT_FROM_GETTER(int, LOGDEBUG);
SWIG_CONSTANT_FROM_GETTER(int, LOGINFO);
- SWIG_CONSTANT_FROM_GETTER(int, LOGNOTICE);
SWIG_CONSTANT_FROM_GETTER(int, LOGWARNING);
SWIG_CONSTANT_FROM_GETTER(int, LOGERROR);
- SWIG_CONSTANT_FROM_GETTER(int, LOGSEVERE);
SWIG_CONSTANT_FROM_GETTER(int, LOGFATAL);
SWIG_CONSTANT_FROM_GETTER(int, LOGNONE);
diff --git a/xbmc/interfaces/legacy/WindowXML.h b/xbmc/interfaces/legacy/WindowXML.h
index c253bd739b..349b0a0f13 100644
--- a/xbmc/interfaces/legacy/WindowXML.h
+++ b/xbmc/interfaces/legacy/WindowXML.h
@@ -39,7 +39,7 @@ namespace XBMCAddon
/// look for.
/// @param scriptPath string - path to script. used to
/// fallback to if the xml doesn't exist in
- /// the current skin. (eg xbmcaddon.Addon().getAddonInfo('path').decode('utf-8'))
+ /// the current skin. (eg xbmcaddon.Addon().getAddonInfo('path'))
/// @param defaultSkin [opt] string - name of the folder in the
/// skins path to look in for the xml.
/// (default='Default')
@@ -62,7 +62,7 @@ namespace XBMCAddon
/// **Example:**
/// ~~~~~~~~~~~~~{.py}
/// ..
- /// win = xbmcgui.WindowXML('script-Lyrics-main.xml', xbmcaddon.Addon().getAddonInfo('path').decode('utf-8'), 'default', '1080i', False)
+ /// win = xbmcgui.WindowXML('script-Lyrics-main.xml', xbmcaddon.Addon().getAddonInfo('path'), 'default', '1080i', False)
/// win.doModal()
/// del win
/// ..
@@ -463,7 +463,7 @@ namespace XBMCAddon
/// look for.
/// @param scriptPath string - path to script. used to
/// fallback to if the xml doesn't exist in
- /// the current skin. (eg \ref python_xbmcaddon_Addon "xbmcaddon.Addon().getAddonInfo('path').decode('utf-8'))"
+ /// the current skin. (eg \ref python_xbmcaddon_Addon "xbmcaddon.Addon().getAddonInfo('path'))"
/// @param defaultSkin [opt] string - name of the folder in the
/// skins path to look in for the xml.
/// (default='Default')
@@ -479,7 +479,7 @@ namespace XBMCAddon
/// **Example:**
/// ~~~~~~~~~~~~~{.py}
/// ..
- /// dialog = xbmcgui.WindowXMLDialog('script-Lyrics-main.xml', xbmcaddon.Addon().getAddonInfo('path').decode('utf-8'), 'default', '1080i')
+ /// dialog = xbmcgui.WindowXMLDialog('script-Lyrics-main.xml', xbmcaddon.Addon().getAddonInfo('path'), 'default', '1080i')
/// dialog.doModal()
/// del dialog
/// ..
diff --git a/xbmc/listproviders/DirectoryProvider.cpp b/xbmc/listproviders/DirectoryProvider.cpp
index bccbd9b39a..ea351da88c 100644
--- a/xbmc/listproviders/DirectoryProvider.cpp
+++ b/xbmc/listproviders/DirectoryProvider.cpp
@@ -289,7 +289,8 @@ void CDirectoryProvider::OnAddonEvent(const ADDON::AddonEvent& event)
typeid(event) == typeid(ADDON::AddonEvents::Disabled) ||
typeid(event) == typeid(ADDON::AddonEvents::ReInstalled) ||
typeid(event) == typeid(ADDON::AddonEvents::UnInstalled) ||
- typeid(event) == typeid(ADDON::AddonEvents::MetadataChanged))
+ typeid(event) == typeid(ADDON::AddonEvents::MetadataChanged) ||
+ typeid(event) == typeid(ADDON::AddonEvents::AutoUpdateStateChanged))
m_updateState = INVALIDATED;
}
}
diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp
index b80ca85c91..574e7a06c9 100644
--- a/xbmc/music/MusicDatabase.cpp
+++ b/xbmc/music/MusicDatabase.cpp
@@ -445,6 +445,7 @@ void CMusicDatabase::CreateViews()
" iSampleRate, "
" iChannels, "
" album.iAlbumDuration AS iAlbumDuration, "
+ " album.iDiscTotal as iDiscTotal, "
" song.dateAdded as dateAdded, "
" song.dateNew AS dateNew, "
" song.dateModified AS dateModified "
@@ -2832,6 +2833,7 @@ void CMusicDatabase::GetFileItemFromDataset(const dbiplus::sql_record* const rec
ReplayGain replaygain;
replaygain.Set(record->at(song_strReplayGain).get_asString());
item->GetMusicInfoTag()->SetReplayGain(replaygain);
+ item->GetMusicInfoTag()->SetTotalDiscs(record->at(song_iDiscTotal).get_asInt());
item->GetMusicInfoTag()->SetLoaded(true);
// Get filename with full path
@@ -8598,7 +8600,7 @@ void CMusicDatabase::UpdateTables(int version)
int CMusicDatabase::GetSchemaVersion() const
{
- return 80;
+ return 81; // Bump version to add iDisctotal to songview for MusicPlayer infolabel and boolean
}
int CMusicDatabase::GetMusicNeedsTagScan()
diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h
index 606407604c..a7005a199f 100644
--- a/xbmc/music/MusicDatabase.h
+++ b/xbmc/music/MusicDatabase.h
@@ -831,6 +831,7 @@ private:
song_iSampleRate,
song_iChannels,
song_iAlbumDuration,
+ song_iDiscTotal,
song_dateAdded,
song_dateNew,
song_dateModified,
diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp
index f71b6c2d8f..1b768ccedf 100644
--- a/xbmc/network/AirTunesServer.cpp
+++ b/xbmc/network/AirTunesServer.cpp
@@ -535,11 +535,9 @@ void shairplay_log(void *cls, int level, const char *msg)
switch(level)
{
case RAOP_LOG_EMERG: // system is unusable
- xbmcLevel = LOGFATAL;
- break;
case RAOP_LOG_ALERT: // action must be taken immediately
case RAOP_LOG_CRIT: // critical conditions
- xbmcLevel = LOGSEVERE;
+ xbmcLevel = LOGFATAL;
break;
case RAOP_LOG_ERR: // error conditions
xbmcLevel = LOGERROR;
@@ -548,8 +546,6 @@ void shairplay_log(void *cls, int level, const char *msg)
xbmcLevel = LOGWARNING;
break;
case RAOP_LOG_NOTICE: // normal but significant condition
- xbmcLevel = LOGNOTICE;
- break;
case RAOP_LOG_INFO: // informational
xbmcLevel = LOGINFO;
break;
diff --git a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp
index 70824876de..f2dabfc304 100644
--- a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp
+++ b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp
@@ -27,7 +27,7 @@
"" \
"import " MODULE "\n" \
"class xbmcout:\n" \
- " def __init__(self, loglevel=" MODULE ".LOGNOTICE):\n" \
+ " def __init__(self, loglevel=" MODULE ".LOGINFO):\n" \
" self.ll=loglevel\n" \
" def write(self, data):\n" \
" " MODULE ".log(data,self.ll)\n" \
@@ -54,7 +54,7 @@
""
#define RUNSCRIPT_POSTSCRIPT \
- MODULE ".log('-->HTTP Python WSGI Interpreter Initialized<--', " MODULE ".LOGNOTICE)\n" \
+ MODULE ".log('-->HTTP Python WSGI Interpreter Initialized<--', " MODULE ".LOGINFO)\n" \
""
#if defined(TARGET_ANDROID)
diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h
index 8a5176601b..82422491d2 100644
--- a/xbmc/peripherals/PeripheralTypes.h
+++ b/xbmc/peripherals/PeripheralTypes.h
@@ -28,7 +28,6 @@ enum PeripheralBusType
PERIPHERAL_BUS_UNKNOWN = 0,
PERIPHERAL_BUS_USB,
PERIPHERAL_BUS_PCI,
- PERIPHERAL_BUS_RPI,
PERIPHERAL_BUS_CEC,
PERIPHERAL_BUS_ADDON,
#ifdef TARGET_ANDROID
@@ -183,8 +182,6 @@ public:
return "usb";
case PERIPHERAL_BUS_PCI:
return "pci";
- case PERIPHERAL_BUS_RPI:
- return "rpi";
case PERIPHERAL_BUS_CEC:
return "cec";
case PERIPHERAL_BUS_ADDON:
@@ -213,8 +210,6 @@ public:
return PERIPHERAL_BUS_USB;
else if (strTypeLowerCase == "pci")
return PERIPHERAL_BUS_PCI;
- else if (strTypeLowerCase == "rpi")
- return PERIPHERAL_BUS_RPI;
else if (strTypeLowerCase == "cec")
return PERIPHERAL_BUS_CEC;
else if (strTypeLowerCase == "addon")
diff --git a/xbmc/peripherals/addons/AddonButtonMap.h b/xbmc/peripherals/addons/AddonButtonMap.h
index fa6a6b19ef..eaf694d889 100644
--- a/xbmc/peripherals/addons/AddonButtonMap.h
+++ b/xbmc/peripherals/addons/AddonButtonMap.h
@@ -9,7 +9,6 @@
#pragma once
#include "PeripheralAddon.h" // for FeatureMap
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
#include "input/joysticks/DriverPrimitive.h"
#include "input/joysticks/JoystickTypes.h"
#include "input/joysticks/interfaces/IButtonMap.h"
diff --git a/xbmc/peripherals/addons/PeripheralAddon.cpp b/xbmc/peripherals/addons/PeripheralAddon.cpp
index 9a4a33aca3..8a9a942231 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddon.cpp
@@ -58,12 +58,21 @@ CPeripheralAddon::CPeripheralAddon(const ADDON::AddonInfoPtr& addonInfo, CPeriph
m_bProvidesButtonMaps =
addonInfo->Type(ADDON::ADDON_PERIPHERALDLL)->GetValue("@provides_buttonmaps").asBoolean();
+ // Create "C" interface structures, used as own parts to prevent API problems on update
+ m_struct.props = new AddonProps_Peripheral();
+ m_struct.toAddon = new KodiToAddonFuncTable_Peripheral();
+ m_struct.toKodi = new AddonToKodiFuncTable_Peripheral();
+
ResetProperties();
}
CPeripheralAddon::~CPeripheralAddon(void)
{
DestroyAddon();
+
+ delete m_struct.toAddon;
+ delete m_struct.toKodi;
+ delete m_struct.props;
}
void CPeripheralAddon::ResetProperties(void)
@@ -72,15 +81,16 @@ void CPeripheralAddon::ResetProperties(void)
m_strUserPath = CSpecialProtocol::TranslatePath(Profile());
m_strClientPath = CSpecialProtocol::TranslatePath(Path());
- m_struct = {{0}};
- m_struct.props.user_path = m_strUserPath.c_str();
- m_struct.props.addon_path = m_strClientPath.c_str();
+ m_struct.props->user_path = m_strUserPath.c_str();
+ m_struct.props->addon_path = m_strClientPath.c_str();
+
+ m_struct.toKodi->kodiInstance = this;
+ m_struct.toKodi->feature_count = cb_feature_count;
+ m_struct.toKodi->feature_type = cb_feature_type;
+ m_struct.toKodi->refresh_button_maps = cb_refresh_button_maps;
+ m_struct.toKodi->trigger_scan = cb_trigger_scan;
- m_struct.toKodi.kodiInstance = this;
- m_struct.toKodi.feature_count = cb_feature_count;
- m_struct.toKodi.feature_type = cb_feature_type;
- m_struct.toKodi.refresh_button_maps = cb_refresh_button_maps;
- m_struct.toKodi.trigger_scan = cb_trigger_scan;
+ memset(m_struct.toAddon, 0, sizeof(KodiToAddonFuncTable_Peripheral));
}
bool CPeripheralAddon::CreateAddon(void)
@@ -135,7 +145,7 @@ bool CPeripheralAddon::GetAddonProperties(void)
PERIPHERAL_CAPABILITIES addonCapabilities = {};
// Get the capabilities
- m_struct.toAddon.get_capabilities(&m_struct, &addonCapabilities);
+ m_struct.toAddon->get_capabilities(&m_struct, &addonCapabilities);
// Verify capabilities against addon.xml
if (m_bProvidesJoysticks != addonCapabilities.provides_joysticks)
@@ -349,11 +359,11 @@ bool CPeripheralAddon::PerformDeviceScan(PeripheralScanResults& results)
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.perform_device_scan)
+ if (!m_struct.toAddon->perform_device_scan)
return false;
LogError(retVal =
- m_struct.toAddon.perform_device_scan(&m_struct, &peripheralCount, &pScanResults),
+ m_struct.toAddon->perform_device_scan(&m_struct, &peripheralCount, &pScanResults),
"PerformDeviceScan()");
if (retVal == PERIPHERAL_NO_ERROR)
@@ -383,7 +393,7 @@ bool CPeripheralAddon::PerformDeviceScan(PeripheralScanResults& results)
results.m_results.push_back(result);
}
- m_struct.toAddon.free_scan_results(&m_struct, peripheralCount, pScanResults);
+ m_struct.toAddon->free_scan_results(&m_struct, peripheralCount, pScanResults);
return true;
}
@@ -398,7 +408,7 @@ bool CPeripheralAddon::ProcessEvents(void)
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.get_events)
+ if (!m_struct.toAddon->get_events)
return false;
PERIPHERAL_ERROR retVal;
@@ -406,7 +416,7 @@ bool CPeripheralAddon::ProcessEvents(void)
unsigned int eventCount = 0;
PERIPHERAL_EVENT* pEvents = nullptr;
- LogError(retVal = m_struct.toAddon.get_events(&m_struct, &eventCount, &pEvents), "GetEvents()");
+ LogError(retVal = m_struct.toAddon->get_events(&m_struct, &eventCount, &pEvents), "GetEvents()");
if (retVal == PERIPHERAL_NO_ERROR)
{
for (unsigned int i = 0; i < eventCount; i++)
@@ -459,7 +469,7 @@ bool CPeripheralAddon::ProcessEvents(void)
std::static_pointer_cast<CPeripheralJoystick>(it.second)->ProcessAxisMotions();
}
- m_struct.toAddon.free_events(&m_struct, eventCount, pEvents);
+ m_struct.toAddon->free_events(&m_struct, eventCount, pEvents);
return true;
}
@@ -476,7 +486,7 @@ bool CPeripheralAddon::SendRumbleEvent(unsigned int peripheralIndex,
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.send_event)
+ if (!m_struct.toAddon->send_event)
return false;
PERIPHERAL_EVENT eventStruct = {};
@@ -486,7 +496,7 @@ bool CPeripheralAddon::SendRumbleEvent(unsigned int peripheralIndex,
eventStruct.driver_index = driverIndex;
eventStruct.motor_state = magnitude;
- return m_struct.toAddon.send_event(&m_struct, &eventStruct);
+ return m_struct.toAddon->send_event(&m_struct, &eventStruct);
}
bool CPeripheralAddon::GetJoystickProperties(unsigned int index, CPeripheralJoystick& joystick)
@@ -496,21 +506,21 @@ bool CPeripheralAddon::GetJoystickProperties(unsigned int index, CPeripheralJoys
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.get_joystick_info)
+ if (!m_struct.toAddon->get_joystick_info)
return false;
PERIPHERAL_ERROR retVal;
JOYSTICK_INFO joystickStruct;
- LogError(retVal = m_struct.toAddon.get_joystick_info(&m_struct, index, &joystickStruct),
+ LogError(retVal = m_struct.toAddon->get_joystick_info(&m_struct, index, &joystickStruct),
"GetJoystickInfo()");
if (retVal == PERIPHERAL_NO_ERROR)
{
kodi::addon::Joystick addonJoystick(joystickStruct);
SetJoystickInfo(joystick, addonJoystick);
- m_struct.toAddon.free_joystick_info(&m_struct, &joystickStruct);
+ m_struct.toAddon->free_joystick_info(&m_struct, &joystickStruct);
return true;
}
@@ -527,7 +537,7 @@ bool CPeripheralAddon::GetFeatures(const CPeripheral* device,
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.get_features)
+ if (!m_struct.toAddon->get_features)
return false;
PERIPHERAL_ERROR retVal;
@@ -541,7 +551,7 @@ bool CPeripheralAddon::GetFeatures(const CPeripheral* device,
unsigned int featureCount = 0;
JOYSTICK_FEATURE* pFeatures = nullptr;
- LogError(retVal = m_struct.toAddon.get_features(
+ LogError(retVal = m_struct.toAddon->get_features(
&m_struct, &joystickStruct, strControllerId.c_str(), &featureCount, &pFeatures),
"GetFeatures()");
@@ -556,7 +566,7 @@ bool CPeripheralAddon::GetFeatures(const CPeripheral* device,
features[feature.Name()] = std::move(feature);
}
- m_struct.toAddon.free_features(&m_struct, featureCount, pFeatures);
+ m_struct.toAddon->free_features(&m_struct, featureCount, pFeatures);
return true;
}
@@ -573,7 +583,7 @@ bool CPeripheralAddon::MapFeature(const CPeripheral* device,
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.map_features)
+ if (!m_struct.toAddon->map_features)
return false;
PERIPHERAL_ERROR retVal;
@@ -587,7 +597,7 @@ bool CPeripheralAddon::MapFeature(const CPeripheral* device,
JOYSTICK_FEATURE addonFeature;
feature.ToStruct(addonFeature);
- LogError(retVal = m_struct.toAddon.map_features(&m_struct, &joystickStruct,
+ LogError(retVal = m_struct.toAddon->map_features(&m_struct, &joystickStruct,
strControllerId.c_str(), 1, &addonFeature),
"MapFeatures()");
@@ -604,7 +614,7 @@ bool CPeripheralAddon::GetIgnoredPrimitives(const CPeripheral* device, Primitive
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.get_ignored_primitives)
+ if (!m_struct.toAddon->get_ignored_primitives)
return false;
PERIPHERAL_ERROR retVal;
@@ -618,7 +628,7 @@ bool CPeripheralAddon::GetIgnoredPrimitives(const CPeripheral* device, Primitive
unsigned int primitiveCount = 0;
JOYSTICK_DRIVER_PRIMITIVE* pPrimitives = nullptr;
- LogError(retVal = m_struct.toAddon.get_ignored_primitives(&m_struct, &joystickStruct,
+ LogError(retVal = m_struct.toAddon->get_ignored_primitives(&m_struct, &joystickStruct,
&primitiveCount, &pPrimitives),
"GetIgnoredPrimitives()");
@@ -629,7 +639,7 @@ bool CPeripheralAddon::GetIgnoredPrimitives(const CPeripheral* device, Primitive
for (unsigned int i = 0; i < primitiveCount; i++)
primitives.emplace_back(pPrimitives[i]);
- m_struct.toAddon.free_primitives(&m_struct, primitiveCount, pPrimitives);
+ m_struct.toAddon->free_primitives(&m_struct, primitiveCount, pPrimitives);
return true;
}
@@ -645,7 +655,7 @@ bool CPeripheralAddon::SetIgnoredPrimitives(const CPeripheral* device,
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.set_ignored_primitives)
+ if (!m_struct.toAddon->set_ignored_primitives)
return false;
PERIPHERAL_ERROR retVal;
@@ -660,7 +670,7 @@ bool CPeripheralAddon::SetIgnoredPrimitives(const CPeripheral* device,
kodi::addon::DriverPrimitives::ToStructs(primitives, &addonPrimitives);
const unsigned int primitiveCount = static_cast<unsigned int>(primitives.size());
- LogError(retVal = m_struct.toAddon.set_ignored_primitives(&m_struct, &joystickStruct,
+ LogError(retVal = m_struct.toAddon->set_ignored_primitives(&m_struct, &joystickStruct,
primitiveCount, addonPrimitives),
"SetIgnoredPrimitives()");
@@ -677,7 +687,7 @@ void CPeripheralAddon::SaveButtonMap(const CPeripheral* device)
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.save_button_map)
+ if (!m_struct.toAddon->save_button_map)
return;
kodi::addon::Joystick joystickInfo;
@@ -686,7 +696,7 @@ void CPeripheralAddon::SaveButtonMap(const CPeripheral* device)
JOYSTICK_INFO joystickStruct;
joystickInfo.ToStruct(joystickStruct);
- m_struct.toAddon.save_button_map(&m_struct, &joystickStruct);
+ m_struct.toAddon->save_button_map(&m_struct, &joystickStruct);
kodi::addon::Joystick::FreeStruct(joystickStruct);
@@ -701,7 +711,7 @@ void CPeripheralAddon::RevertButtonMap(const CPeripheral* device)
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.revert_button_map)
+ if (!m_struct.toAddon->revert_button_map)
return;
kodi::addon::Joystick joystickInfo;
@@ -710,7 +720,7 @@ void CPeripheralAddon::RevertButtonMap(const CPeripheral* device)
JOYSTICK_INFO joystickStruct;
joystickInfo.ToStruct(joystickStruct);
- m_struct.toAddon.revert_button_map(&m_struct, &joystickStruct);
+ m_struct.toAddon->revert_button_map(&m_struct, &joystickStruct);
kodi::addon::Joystick::FreeStruct(joystickStruct);
}
@@ -726,7 +736,7 @@ void CPeripheralAddon::ResetButtonMap(const CPeripheral* device, const std::stri
JOYSTICK_INFO joystickStruct;
joystickInfo.ToStruct(joystickStruct);
- m_struct.toAddon.reset_button_map(&m_struct, &joystickStruct, strControllerId.c_str());
+ m_struct.toAddon->reset_button_map(&m_struct, &joystickStruct, strControllerId.c_str());
kodi::addon::Joystick::FreeStruct(joystickStruct);
@@ -744,10 +754,10 @@ void CPeripheralAddon::PowerOffJoystick(unsigned int index)
CSharedLock lock(m_dllSection);
- if (!m_struct.toAddon.power_off_joystick)
+ if (!m_struct.toAddon->power_off_joystick)
return;
- m_struct.toAddon.power_off_joystick(&m_struct, index);
+ m_struct.toAddon->power_off_joystick(&m_struct, index);
}
void CPeripheralAddon::RegisterButtonMap(CPeripheral* device, IButtonMap* buttonMap)
diff --git a/xbmc/peripherals/addons/PeripheralAddon.h b/xbmc/peripherals/addons/PeripheralAddon.h
index 69952e6ed8..9ad8b5f67f 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.h
+++ b/xbmc/peripherals/addons/PeripheralAddon.h
@@ -10,7 +10,6 @@
#include "addons/binary-addons/AddonInstanceHandler.h"
#include "addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h"
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
#include "input/joysticks/JoystickTypes.h"
#include "peripherals/PeripheralTypes.h"
#include "threads/CriticalSection.h"
diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.h b/xbmc/peripherals/addons/PeripheralAddonTranslator.h
index a09defe8cd..308d62c904 100644
--- a/xbmc/peripherals/addons/PeripheralAddonTranslator.h
+++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.h
@@ -9,7 +9,6 @@
#pragma once
#include "addons/kodi-dev-kit/include/kodi/addon-instance/Peripheral.h"
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
#include "input/joysticks/DriverPrimitive.h"
#include "input/joysticks/JoystickTypes.h"
#include "input/mouse/MouseTypes.h"
diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp
index 0cbcd67785..e119638bc0 100644
--- a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp
+++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp
@@ -45,11 +45,6 @@ bool CPeripheralBusCEC::PerformDeviceScan(PeripheralScanResults& results)
case ADAPTERTYPE_P8_DAUGHTERBOARD:
result.m_mappedBusType = PERIPHERAL_BUS_USB;
break;
- case ADAPTERTYPE_RPI:
- result.m_mappedBusType = PERIPHERAL_BUS_RPI;
- /** the Pi's adapter cannot be removed, no need to rescan */
- m_bNeedsPolling = false;
- break;
default:
break;
}
diff --git a/xbmc/pictures/Picture.cpp b/xbmc/pictures/Picture.cpp
index 9816ae6a1d..e24f613dd7 100644
--- a/xbmc/pictures/Picture.cpp
+++ b/xbmc/pictures/Picture.cpp
@@ -20,9 +20,6 @@
#include "utils/URIUtils.h"
#include "guilib/Texture.h"
#include "guilib/imagefactory.h"
-#if defined(TARGET_RASPBERRY_PI)
-#include "cores/omxplayer/OMXImage.h"
-#endif
extern "C" {
#include <libswscale/swscale.h>
@@ -58,13 +55,6 @@ bool CPicture::GetThumbnailFromSurface(const unsigned char* buffer, int width, i
bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width, int height, int stride, const std::string &thumbFile)
{
CLog::Log(LOGDEBUG, "cached image '%s' size %dx%d", CURL::GetRedacted(thumbFile).c_str(), width, height);
- if (URIUtils::HasExtension(thumbFile, ".jpg"))
- {
-#if defined(TARGET_RASPBERRY_PI)
- if (COMXImage::CreateThumbnailFromSurface(const_cast<unsigned char*>(buffer), width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str()))
- return true;
-#endif
- }
unsigned char *thumb = NULL;
unsigned int thumbsize=0;
diff --git a/xbmc/pictures/PictureInfoTag.cpp b/xbmc/pictures/PictureInfoTag.cpp
index ccf89aebc1..f3a34ce985 100644
--- a/xbmc/pictures/PictureInfoTag.cpp
+++ b/xbmc/pictures/PictureInfoTag.cpp
@@ -17,10 +17,103 @@
#include <algorithm>
#include <vector>
+CPictureInfoTag::ExifInfo::ExifInfo(const ExifInfo_t& other)
+ : CameraMake(other.CameraMake),
+ CameraModel(other.CameraModel),
+ DateTime(other.DateTime),
+ Height(other.Height),
+ Width(other.Width),
+ Orientation(other.Orientation),
+ IsColor(other.IsColor),
+ Process(other.Process),
+ FlashUsed(other.FlashUsed),
+ FocalLength(other.FocalLength),
+ ExposureTime(other.ExposureTime),
+ ApertureFNumber(other.ApertureFNumber),
+ Distance(other.Distance),
+ CCDWidth(other.CCDWidth),
+ ExposureBias(other.ExposureBias),
+ DigitalZoomRatio(other.DigitalZoomRatio),
+ FocalLength35mmEquiv(other.FocalLength35mmEquiv),
+ Whitebalance(other.Whitebalance),
+ MeteringMode(other.MeteringMode),
+ ExposureProgram(other.ExposureProgram),
+ ExposureMode(other.ExposureMode),
+ ISOequivalent(other.ISOequivalent),
+ LightSource(other.LightSource),
+ CommentsCharset(EXIF_COMMENT_CHARSET_CONVERTED),
+ XPCommentsCharset(EXIF_COMMENT_CHARSET_CONVERTED),
+ Comments(Convert(other.CommentsCharset, other.Comments)),
+ FileComment(Convert(EXIF_COMMENT_CHARSET_UNKNOWN, other.FileComment)),
+ XPComment(Convert(other.XPCommentsCharset, other.XPComment)),
+ Description(other.Description),
+ ThumbnailOffset(other.ThumbnailOffset),
+ ThumbnailSize(other.ThumbnailSize),
+ LargestExifOffset(other.LargestExifOffset),
+ ThumbnailAtEnd(other.ThumbnailAtEnd),
+ ThumbnailSizeOffset(other.ThumbnailSizeOffset),
+ DateTimeOffsets(other.DateTimeOffsets, other.DateTimeOffsets + other.numDateTimeTags),
+ GpsInfoPresent(other.GpsInfoPresent),
+ GpsLat(other.GpsLat),
+ GpsLong(other.GpsLong),
+ GpsAlt(other.GpsAlt)
+{
+}
+
+std::string CPictureInfoTag::ExifInfo::Convert(int charset, const char* data)
+{
+ std::string value;
+
+ // The charset used for the UserComment is stored in CommentsCharset:
+ // Ascii, Unicode (UCS2), JIS (X208-1990), Unknown (application specific)
+ if (charset == EXIF_COMMENT_CHARSET_UNICODE)
+ {
+ g_charsetConverter.ucs2ToUTF8(std::u16string(reinterpret_cast<const char16_t*>(data)), value);
+ }
+ else
+ {
+ // Ascii doesn't need to be converted (EXIF_COMMENT_CHARSET_ASCII)
+ // Unknown data can't be converted as it could be any codec (EXIF_COMMENT_CHARSET_UNKNOWN)
+ // JIS data can't be converted as CharsetConverter and iconv lacks support (EXIF_COMMENT_CHARSET_JIS)
+ g_charsetConverter.unknownToUTF8(data, value);
+ }
+
+ return value;
+}
+
+CPictureInfoTag::IPTCInfo::IPTCInfo(const IPTCInfo_t& other)
+ : RecordVersion(other.RecordVersion),
+ SupplementalCategories(other.SupplementalCategories),
+ Keywords(other.Keywords),
+ Caption(other.Caption),
+ Author(other.Author),
+ Headline(other.Headline),
+ SpecialInstructions(other.SpecialInstructions),
+ Category(other.Category),
+ Byline(other.Byline),
+ BylineTitle(other.BylineTitle),
+ Credit(other.Credit),
+ Source(other.Source),
+ CopyrightNotice(other.CopyrightNotice),
+ ObjectName(other.ObjectName),
+ City(other.City),
+ State(other.State),
+ Country(other.Country),
+ TransmissionReference(other.TransmissionReference),
+ Date(other.Date),
+ Urgency(other.Urgency),
+ ReferenceService(other.ReferenceService),
+ CountryCode(other.CountryCode),
+ TimeCreated(other.TimeCreated),
+ SubLocation(other.SubLocation),
+ ImageType(other.ImageType)
+{
+}
+
void CPictureInfoTag::Reset()
{
- memset(&m_exifInfo, 0, sizeof(m_exifInfo));
- memset(&m_iptcInfo, 0, sizeof(m_iptcInfo));
+ m_exifInfo = {};
+ m_iptcInfo = {};
m_isLoaded = false;
m_isInfoSetExternally = false;
m_dateTimeTaken.Reset();
@@ -30,8 +123,15 @@ bool CPictureInfoTag::Load(const std::string &path)
{
m_isLoaded = false;
- if (process_jpeg(path.c_str(), &m_exifInfo, &m_iptcInfo))
+ ExifInfo_t exifInfo;
+ IPTCInfo_t iptcInfo;
+
+ if (process_jpeg(path.c_str(), &exifInfo, &iptcInfo))
+ {
+ m_exifInfo = ExifInfo(exifInfo);
+ m_iptcInfo = IPTCInfo(iptcInfo);
m_isLoaded = true;
+ }
ConvertDateTime();
@@ -45,14 +145,19 @@ void CPictureInfoTag::Archive(CArchive& ar)
ar << m_isLoaded;
ar << m_isInfoSetExternally;
ar << m_exifInfo.ApertureFNumber;
- ar << std::string(m_exifInfo.CameraMake);
- ar << std::string(m_exifInfo.CameraModel);
+ ar << m_exifInfo.CameraMake;
+ ar << m_exifInfo.CameraModel;
ar << m_exifInfo.CCDWidth;
- ar << GetInfo(SLIDESHOW_EXIF_COMMENT); // Store and restore the comment charset converted
- ar << std::string(m_exifInfo.Description);
- ar << std::string(m_exifInfo.DateTime);
- for (int dateTimeOffset : m_exifInfo.DateTimeOffsets)
- ar << dateTimeOffset;
+ ar << m_exifInfo.Comments;
+ ar << m_exifInfo.Description;
+ ar << m_exifInfo.DateTime;
+ for (std::vector<int>::size_type i = 0; i < MAX_DATE_COPIES; ++i)
+ {
+ if (i < m_exifInfo.DateTimeOffsets.size())
+ ar << m_exifInfo.DateTimeOffsets[i];
+ else
+ ar << static_cast<int>(0);
+ }
ar << m_exifInfo.DigitalZoomRatio;
ar << m_exifInfo.Distance;
ar << m_exifInfo.ExposureBias;
@@ -63,16 +168,16 @@ void CPictureInfoTag::Archive(CArchive& ar)
ar << m_exifInfo.FocalLength;
ar << m_exifInfo.FocalLength35mmEquiv;
ar << m_exifInfo.GpsInfoPresent;
- ar << std::string(m_exifInfo.GpsAlt);
- ar << std::string(m_exifInfo.GpsLat);
- ar << std::string(m_exifInfo.GpsLong);
+ ar << m_exifInfo.GpsAlt;
+ ar << m_exifInfo.GpsLat;
+ ar << m_exifInfo.GpsLong;
ar << m_exifInfo.Height;
ar << m_exifInfo.IsColor;
ar << m_exifInfo.ISOequivalent;
ar << m_exifInfo.LargestExifOffset;
ar << m_exifInfo.LightSource;
ar << m_exifInfo.MeteringMode;
- ar << m_exifInfo.numDateTimeTags;
+ ar << static_cast<int>(m_exifInfo.DateTimeOffsets.size());
ar << m_exifInfo.Orientation;
ar << m_exifInfo.Process;
ar << m_exifInfo.ThumbnailAtEnd;
@@ -83,45 +188,51 @@ void CPictureInfoTag::Archive(CArchive& ar)
ar << m_exifInfo.Width;
ar << m_dateTimeTaken;
- ar << std::string(m_iptcInfo.Author);
- ar << std::string(m_iptcInfo.Byline);
- ar << std::string(m_iptcInfo.BylineTitle);
- ar << std::string(m_iptcInfo.Caption);
- ar << std::string(m_iptcInfo.Category);
- ar << std::string(m_iptcInfo.City);
- ar << std::string(m_iptcInfo.Urgency);
- ar << std::string(m_iptcInfo.CopyrightNotice);
- ar << std::string(m_iptcInfo.Country);
- ar << std::string(m_iptcInfo.CountryCode);
- ar << std::string(m_iptcInfo.Credit);
- ar << std::string(m_iptcInfo.Date);
- ar << std::string(m_iptcInfo.Headline);
- ar << std::string(m_iptcInfo.Keywords);
- ar << std::string(m_iptcInfo.ObjectName);
- ar << std::string(m_iptcInfo.ReferenceService);
- ar << std::string(m_iptcInfo.Source);
- ar << std::string(m_iptcInfo.SpecialInstructions);
- ar << std::string(m_iptcInfo.State);
- ar << std::string(m_iptcInfo.SupplementalCategories);
- ar << std::string(m_iptcInfo.TransmissionReference);
- ar << std::string(m_iptcInfo.TimeCreated);
- ar << std::string(m_iptcInfo.SubLocation);
- ar << std::string(m_iptcInfo.ImageType);
+ ar << m_iptcInfo.Author;
+ ar << m_iptcInfo.Byline;
+ ar << m_iptcInfo.BylineTitle;
+ ar << m_iptcInfo.Caption;
+ ar << m_iptcInfo.Category;
+ ar << m_iptcInfo.City;
+ ar << m_iptcInfo.Urgency;
+ ar << m_iptcInfo.CopyrightNotice;
+ ar << m_iptcInfo.Country;
+ ar << m_iptcInfo.CountryCode;
+ ar << m_iptcInfo.Credit;
+ ar << m_iptcInfo.Date;
+ ar << m_iptcInfo.Headline;
+ ar << m_iptcInfo.Keywords;
+ ar << m_iptcInfo.ObjectName;
+ ar << m_iptcInfo.ReferenceService;
+ ar << m_iptcInfo.Source;
+ ar << m_iptcInfo.SpecialInstructions;
+ ar << m_iptcInfo.State;
+ ar << m_iptcInfo.SupplementalCategories;
+ ar << m_iptcInfo.TransmissionReference;
+ ar << m_iptcInfo.TimeCreated;
+ ar << m_iptcInfo.SubLocation;
+ ar << m_iptcInfo.ImageType;
}
else
{
ar >> m_isLoaded;
ar >> m_isInfoSetExternally;
ar >> m_exifInfo.ApertureFNumber;
- GetStringFromArchive(ar, m_exifInfo.CameraMake, sizeof(m_exifInfo.CameraMake));
- GetStringFromArchive(ar, m_exifInfo.CameraModel, sizeof(m_exifInfo.CameraModel));
+ ar >> m_exifInfo.CameraMake;
+ ar >> m_exifInfo.CameraModel;
ar >> m_exifInfo.CCDWidth;
- GetStringFromArchive(ar, m_exifInfo.Comments, sizeof(m_exifInfo.Comments));
+ ar >> m_exifInfo.Comments;
m_exifInfo.CommentsCharset = EXIF_COMMENT_CHARSET_CONVERTED; // Store and restore the comment charset converted
- GetStringFromArchive(ar, m_exifInfo.Description, sizeof(m_exifInfo.Description));
- GetStringFromArchive(ar, m_exifInfo.DateTime, sizeof(m_exifInfo.DateTime));
- for (int& dateTimeOffset : m_exifInfo.DateTimeOffsets)
+ ar >> m_exifInfo.Description;
+ ar >> m_exifInfo.DateTime;
+ m_exifInfo.DateTimeOffsets.clear();
+ m_exifInfo.DateTimeOffsets.reserve(MAX_DATE_COPIES);
+ for (std::vector<int>::size_type i = 0; i < MAX_DATE_COPIES; ++i)
+ {
+ int dateTimeOffset;
ar >> dateTimeOffset;
+ m_exifInfo.DateTimeOffsets.push_back(dateTimeOffset);
+ }
ar >> m_exifInfo.DigitalZoomRatio;
ar >> m_exifInfo.Distance;
ar >> m_exifInfo.ExposureBias;
@@ -132,16 +243,18 @@ void CPictureInfoTag::Archive(CArchive& ar)
ar >> m_exifInfo.FocalLength;
ar >> m_exifInfo.FocalLength35mmEquiv;
ar >> m_exifInfo.GpsInfoPresent;
- GetStringFromArchive(ar, m_exifInfo.GpsAlt, sizeof(m_exifInfo.GpsAlt));
- GetStringFromArchive(ar, m_exifInfo.GpsLat, sizeof(m_exifInfo.GpsLat));
- GetStringFromArchive(ar, m_exifInfo.GpsLong, sizeof(m_exifInfo.GpsLong));
+ ar >> m_exifInfo.GpsAlt;
+ ar >> m_exifInfo.GpsLat;
+ ar >> m_exifInfo.GpsLong;
ar >> m_exifInfo.Height;
ar >> m_exifInfo.IsColor;
ar >> m_exifInfo.ISOequivalent;
ar >> m_exifInfo.LargestExifOffset;
ar >> m_exifInfo.LightSource;
ar >> m_exifInfo.MeteringMode;
- ar >> m_exifInfo.numDateTimeTags;
+ int numDateTimeTags;
+ ar >> numDateTimeTags;
+ m_exifInfo.DateTimeOffsets.resize(numDateTimeTags);
ar >> m_exifInfo.Orientation;
ar >> m_exifInfo.Process;
ar >> m_exifInfo.ThumbnailAtEnd;
@@ -152,44 +265,49 @@ void CPictureInfoTag::Archive(CArchive& ar)
ar >> m_exifInfo.Width;
ar >> m_dateTimeTaken;
- GetStringFromArchive(ar, m_iptcInfo.Author, sizeof(m_iptcInfo.Author));
- GetStringFromArchive(ar, m_iptcInfo.Byline, sizeof(m_iptcInfo.Byline));
- GetStringFromArchive(ar, m_iptcInfo.BylineTitle, sizeof(m_iptcInfo.BylineTitle));
- GetStringFromArchive(ar, m_iptcInfo.Caption, sizeof(m_iptcInfo.Caption));
- GetStringFromArchive(ar, m_iptcInfo.Category, sizeof(m_iptcInfo.Category));
- GetStringFromArchive(ar, m_iptcInfo.City, sizeof(m_iptcInfo.City));
- GetStringFromArchive(ar, m_iptcInfo.Urgency, sizeof(m_iptcInfo.Urgency));
- GetStringFromArchive(ar, m_iptcInfo.CopyrightNotice, sizeof(m_iptcInfo.CopyrightNotice));
- GetStringFromArchive(ar, m_iptcInfo.Country, sizeof(m_iptcInfo.Country));
- GetStringFromArchive(ar, m_iptcInfo.CountryCode, sizeof(m_iptcInfo.CountryCode));
- GetStringFromArchive(ar, m_iptcInfo.Credit, sizeof(m_iptcInfo.Credit));
- GetStringFromArchive(ar, m_iptcInfo.Date, sizeof(m_iptcInfo.Date));
- GetStringFromArchive(ar, m_iptcInfo.Headline, sizeof(m_iptcInfo.Headline));
- GetStringFromArchive(ar, m_iptcInfo.Keywords, sizeof(m_iptcInfo.Keywords));
- GetStringFromArchive(ar, m_iptcInfo.ObjectName, sizeof(m_iptcInfo.ObjectName));
- GetStringFromArchive(ar, m_iptcInfo.ReferenceService, sizeof(m_iptcInfo.ReferenceService));
- GetStringFromArchive(ar, m_iptcInfo.Source, sizeof(m_iptcInfo.Source));
- GetStringFromArchive(ar, m_iptcInfo.SpecialInstructions, sizeof(m_iptcInfo.SpecialInstructions));
- GetStringFromArchive(ar, m_iptcInfo.State, sizeof(m_iptcInfo.State));
- GetStringFromArchive(ar, m_iptcInfo.SupplementalCategories, sizeof(m_iptcInfo.SupplementalCategories));
- GetStringFromArchive(ar, m_iptcInfo.TransmissionReference, sizeof(m_iptcInfo.TransmissionReference));
- GetStringFromArchive(ar, m_iptcInfo.TimeCreated, sizeof(m_iptcInfo.TimeCreated));
- GetStringFromArchive(ar, m_iptcInfo.SubLocation, sizeof(m_iptcInfo.SubLocation));
- GetStringFromArchive(ar, m_iptcInfo.ImageType, sizeof(m_iptcInfo.ImageType));
+ ar >> m_iptcInfo.Author;
+ ar >> m_iptcInfo.Byline;
+ ar >> m_iptcInfo.BylineTitle;
+ ar >> m_iptcInfo.Caption;
+ ar >> m_iptcInfo.Category;
+ ar >> m_iptcInfo.City;
+ ar >> m_iptcInfo.Urgency;
+ ar >> m_iptcInfo.CopyrightNotice;
+ ar >> m_iptcInfo.Country;
+ ar >> m_iptcInfo.CountryCode;
+ ar >> m_iptcInfo.Credit;
+ ar >> m_iptcInfo.Date;
+ ar >> m_iptcInfo.Headline;
+ ar >> m_iptcInfo.Keywords;
+ ar >> m_iptcInfo.ObjectName;
+ ar >> m_iptcInfo.ReferenceService;
+ ar >> m_iptcInfo.Source;
+ ar >> m_iptcInfo.SpecialInstructions;
+ ar >> m_iptcInfo.State;
+ ar >> m_iptcInfo.SupplementalCategories;
+ ar >> m_iptcInfo.TransmissionReference;
+ ar >> m_iptcInfo.TimeCreated;
+ ar >> m_iptcInfo.SubLocation;
+ ar >> m_iptcInfo.ImageType;
}
}
void CPictureInfoTag::Serialize(CVariant& value) const
{
value["aperturefnumber"] = m_exifInfo.ApertureFNumber;
- value["cameramake"] = std::string(m_exifInfo.CameraMake);
- value["cameramodel"] = std::string(m_exifInfo.CameraModel);
+ value["cameramake"] = m_exifInfo.CameraMake;
+ value["cameramodel"] = m_exifInfo.CameraModel;
value["ccdwidth"] = m_exifInfo.CCDWidth;
- value["comments"] = GetInfo(SLIDESHOW_EXIF_COMMENT); // Charset conversion
- value["description"] = std::string(m_exifInfo.Description);
- value["datetime"] = std::string(m_exifInfo.DateTime);
- for (int i = 0; i < 10; i++)
- value["datetimeoffsets"][i] = m_exifInfo.DateTimeOffsets[i];
+ value["comments"] = m_exifInfo.Comments;
+ value["description"] = m_exifInfo.Description;
+ value["datetime"] = m_exifInfo.DateTime;
+ for (std::vector<int>::size_type i = 0; i < MAX_DATE_COPIES; ++i)
+ {
+ if (i < m_exifInfo.DateTimeOffsets.size())
+ value["datetimeoffsets"][static_cast<int>(i)] = m_exifInfo.DateTimeOffsets[i];
+ else
+ value["datetimeoffsets"][static_cast<int>(i)] = static_cast<int>(0);
+ }
value["digitalzoomratio"] = m_exifInfo.DigitalZoomRatio;
value["distance"] = m_exifInfo.Distance;
value["exposurebias"] = m_exifInfo.ExposureBias;
@@ -200,16 +318,16 @@ void CPictureInfoTag::Serialize(CVariant& value) const
value["focallength"] = m_exifInfo.FocalLength;
value["focallength35mmequiv"] = m_exifInfo.FocalLength35mmEquiv;
value["gpsinfopresent"] = m_exifInfo.GpsInfoPresent;
- value["gpsinfo"]["alt"] = std::string(m_exifInfo.GpsAlt);
- value["gpsinfo"]["lat"] = std::string(m_exifInfo.GpsLat);
- value["gpsinfo"]["long"] = std::string(m_exifInfo.GpsLong);
+ value["gpsinfo"]["alt"] = m_exifInfo.GpsAlt;
+ value["gpsinfo"]["lat"] = m_exifInfo.GpsLat;
+ value["gpsinfo"]["long"] = m_exifInfo.GpsLong;
value["height"] = m_exifInfo.Height;
value["iscolor"] = m_exifInfo.IsColor;
value["isoequivalent"] = m_exifInfo.ISOequivalent;
value["largestexifoffset"] = m_exifInfo.LargestExifOffset;
value["lightsource"] = m_exifInfo.LightSource;
value["meteringmode"] = m_exifInfo.MeteringMode;
- value["numdatetimetags"] = m_exifInfo.numDateTimeTags;
+ value["numdatetimetags"] = static_cast<int>(m_exifInfo.DateTimeOffsets.size());
value["orientation"] = m_exifInfo.Orientation;
value["process"] = m_exifInfo.Process;
value["thumbnailatend"] = m_exifInfo.ThumbnailAtEnd;
@@ -219,30 +337,30 @@ void CPictureInfoTag::Serialize(CVariant& value) const
value["whitebalance"] = m_exifInfo.Whitebalance;
value["width"] = m_exifInfo.Width;
- value["author"] = std::string(m_iptcInfo.Author);
- value["byline"] = std::string(m_iptcInfo.Byline);
- value["bylinetitle"] = std::string(m_iptcInfo.BylineTitle);
- value["caption"] = std::string(m_iptcInfo.Caption);
- value["category"] = std::string(m_iptcInfo.Category);
- value["city"] = std::string(m_iptcInfo.City);
- value["urgency"] = std::string(m_iptcInfo.Urgency);
- value["copyrightnotice"] = std::string(m_iptcInfo.CopyrightNotice);
- value["country"] = std::string(m_iptcInfo.Country);
- value["countrycode"] = std::string(m_iptcInfo.CountryCode);
- value["credit"] = std::string(m_iptcInfo.Credit);
- value["date"] = std::string(m_iptcInfo.Date);
- value["headline"] = std::string(m_iptcInfo.Headline);
- value["keywords"] = std::string(m_iptcInfo.Keywords);
- value["objectname"] = std::string(m_iptcInfo.ObjectName);
- value["referenceservice"] = std::string(m_iptcInfo.ReferenceService);
- value["source"] = std::string(m_iptcInfo.Source);
- value["specialinstructions"] = std::string(m_iptcInfo.SpecialInstructions);
- value["state"] = std::string(m_iptcInfo.State);
- value["supplementalcategories"] = std::string(m_iptcInfo.SupplementalCategories);
- value["transmissionreference"] = std::string(m_iptcInfo.TransmissionReference);
- value["timecreated"] = std::string(m_iptcInfo.TimeCreated);
- value["sublocation"] = std::string(m_iptcInfo.SubLocation);
- value["imagetype"] = std::string(m_iptcInfo.ImageType);
+ value["author"] = m_iptcInfo.Author;
+ value["byline"] = m_iptcInfo.Byline;
+ value["bylinetitle"] = m_iptcInfo.BylineTitle;
+ value["caption"] = m_iptcInfo.Caption;
+ value["category"] = m_iptcInfo.Category;
+ value["city"] = m_iptcInfo.City;
+ value["urgency"] = m_iptcInfo.Urgency;
+ value["copyrightnotice"] = m_iptcInfo.CopyrightNotice;
+ value["country"] = m_iptcInfo.Country;
+ value["countrycode"] = m_iptcInfo.CountryCode;
+ value["credit"] = m_iptcInfo.Credit;
+ value["date"] = m_iptcInfo.Date;
+ value["headline"] = m_iptcInfo.Headline;
+ value["keywords"] = m_iptcInfo.Keywords;
+ value["objectname"] = m_iptcInfo.ObjectName;
+ value["referenceservice"] = m_iptcInfo.ReferenceService;
+ value["source"] = m_iptcInfo.Source;
+ value["specialinstructions"] = m_iptcInfo.SpecialInstructions;
+ value["state"] = m_iptcInfo.State;
+ value["supplementalcategories"] = m_iptcInfo.SupplementalCategories;
+ value["transmissionreference"] = m_iptcInfo.TransmissionReference;
+ value["timecreated"] = m_iptcInfo.TimeCreated;
+ value["sublocation"] = m_iptcInfo.SubLocation;
+ value["imagetype"] = m_iptcInfo.ImageType;
}
void CPictureInfoTag::ToSortable(SortItem& sortable, Field field) const
@@ -251,16 +369,6 @@ void CPictureInfoTag::ToSortable(SortItem& sortable, Field field) const
sortable[FieldDateTaken] = m_dateTimeTaken.GetAsDBDateTime();
}
-void CPictureInfoTag::GetStringFromArchive(CArchive &ar, char *string, size_t length)
-{
- std::string temp;
- ar >> temp;
- length = std::min(temp.size(), length - 1);
- if (!temp.empty())
- memcpy(string, temp.c_str(), length);
- string[length] = 0;
-}
-
const std::string CPictureInfoTag::GetInfo(int info) const
{
if (!m_isLoaded && !m_isInfoSetExternally) // If no metadata has been loaded from the picture file or set with SetInfo(), just return
@@ -299,33 +407,13 @@ const std::string CPictureInfoTag::GetInfo(int info) const
}
break;
case SLIDESHOW_COMMENT:
- g_charsetConverter.unknownToUTF8(m_exifInfo.FileComment, value);
+ value = m_exifInfo.FileComment;
break;
case SLIDESHOW_EXIF_COMMENT:
- // The charset used for the UserComment is stored in CommentsCharset:
- // Ascii, Unicode (UCS2), JIS (X208-1990), Unknown (application specific)
- if (m_exifInfo.CommentsCharset == EXIF_COMMENT_CHARSET_UNICODE)
- {
- g_charsetConverter.ucs2ToUTF8(std::u16string((const char16_t*)m_exifInfo.Comments), value);
- }
- else
- {
- // Ascii doesn't need to be converted (EXIF_COMMENT_CHARSET_ASCII)
- // Archived data is already converted (EXIF_COMMENT_CHARSET_CONVERTED)
- // Unknown data can't be converted as it could be any codec (EXIF_COMMENT_CHARSET_UNKNOWN)
- // JIS data can't be converted as CharsetConverter and iconv lacks support (EXIF_COMMENT_CHARSET_JIS)
- g_charsetConverter.unknownToUTF8(m_exifInfo.Comments, value);
- }
+ value = m_exifInfo.Comments;
break;
case SLIDESHOW_EXIF_XPCOMMENT:
- if (m_exifInfo.XPCommentsCharset == EXIF_COMMENT_CHARSET_UNICODE)
- {
- g_charsetConverter.ucs2ToUTF8(std::u16string((const char16_t*)m_exifInfo.XPComment), value);
- }
- else
- {
- value = "Illegal charset used.";
- }
+ value = m_exifInfo.XPComment;
break;
case SLIDESHOW_EXIF_LONG_DATE_TIME:
if (m_dateTimeTaken.IsValid())
@@ -612,8 +700,7 @@ void CPictureInfoTag::SetInfo(const std::string &key, const std::string& value)
}
case SLIDESHOW_EXIF_DATE_TIME:
{
- strncpy(m_exifInfo.DateTime, value.c_str(), sizeof(m_exifInfo.DateTime) - 1);
- m_exifInfo.DateTime[sizeof(m_exifInfo.DateTime) - 1] = '\0';
+ m_exifInfo.DateTime = value;
m_isInfoSetExternally = true; // Set the internal state to show metadata has been set by call to SetInfo
ConvertDateTime();
break;
@@ -630,9 +717,9 @@ const CDateTime& CPictureInfoTag::GetDateTimeTaken() const
void CPictureInfoTag::ConvertDateTime()
{
- if (strlen(m_exifInfo.DateTime) >= 19 && m_exifInfo.DateTime[0] != ' ')
+ const std::string& dateTime = m_exifInfo.DateTime;
+ if (dateTime.length() >= 19 && dateTime[0] != ' ')
{
- std::string dateTime = m_exifInfo.DateTime;
int year = atoi(dateTime.substr(0, 4).c_str());
int month = atoi(dateTime.substr(5, 2).c_str());
int day = atoi(dateTime.substr(8, 2).c_str());
diff --git a/xbmc/pictures/PictureInfoTag.h b/xbmc/pictures/PictureInfoTag.h
index 6e5fc131bf..1897e900f0 100644
--- a/xbmc/pictures/PictureInfoTag.h
+++ b/xbmc/pictures/PictureInfoTag.h
@@ -15,11 +15,108 @@
#include "utils/ISortable.h"
#include <string>
+#include <vector>
class CVariant;
class CPictureInfoTag : public IArchivable, public ISerializable, public ISortable
{
+ // Mimic structs from libexif.h but with C++ types instead of arrays
+ struct ExifInfo
+ {
+ ExifInfo() = default;
+ ExifInfo(const ExifInfo&) = default;
+ ExifInfo(ExifInfo&&) = default;
+ ExifInfo(const ExifInfo_t& other);
+
+ ExifInfo& operator=(const ExifInfo&) = default;
+ ExifInfo& operator=(ExifInfo&&) = default;
+
+ std::string CameraMake;
+ std::string CameraModel;
+ std::string DateTime;
+ int Height{};
+ int Width{};
+ int Orientation{};
+ int IsColor{};
+ int Process{};
+ int FlashUsed{};
+ float FocalLength{};
+ float ExposureTime{};
+ float ApertureFNumber{};
+ float Distance{};
+ float CCDWidth{};
+ float ExposureBias{};
+ float DigitalZoomRatio{};
+ int FocalLength35mmEquiv{};
+ int Whitebalance{};
+ int MeteringMode{};
+ int ExposureProgram{};
+ int ExposureMode{};
+ int ISOequivalent{};
+ int LightSource{};
+ int CommentsCharset{};
+ int XPCommentsCharset{};
+ std::string Comments;
+ std::string FileComment;
+ std::string XPComment;
+ std::string Description;
+
+ unsigned ThumbnailOffset{};
+ unsigned ThumbnailSize{};
+ unsigned LargestExifOffset{};
+
+ char ThumbnailAtEnd{};
+ int ThumbnailSizeOffset{};
+
+ std::vector<int> DateTimeOffsets;
+
+ int GpsInfoPresent{};
+ std::string GpsLat;
+ std::string GpsLong;
+ std::string GpsAlt;
+
+ private:
+ static std::string Convert(int charset, const char* data);
+ };
+
+ struct IPTCInfo
+ {
+ IPTCInfo() = default;
+ IPTCInfo(const IPTCInfo&) = default;
+ IPTCInfo(IPTCInfo&&) = default;
+ IPTCInfo(const IPTCInfo_t& other);
+
+ IPTCInfo& operator=(const IPTCInfo&) = default;
+ IPTCInfo& operator=(IPTCInfo&&) = default;
+
+ std::string RecordVersion;
+ std::string SupplementalCategories;
+ std::string Keywords;
+ std::string Caption;
+ std::string Author;
+ std::string Headline;
+ std::string SpecialInstructions;
+ std::string Category;
+ std::string Byline;
+ std::string BylineTitle;
+ std::string Credit;
+ std::string Source;
+ std::string CopyrightNotice;
+ std::string ObjectName;
+ std::string City;
+ std::string State;
+ std::string Country;
+ std::string TransmissionReference;
+ std::string Date;
+ std::string Urgency;
+ std::string ReferenceService;
+ std::string CountryCode;
+ std::string TimeCreated;
+ std::string SubLocation;
+ std::string ImageType;
+ };
+
public:
CPictureInfoTag() { Reset(); };
virtual ~CPictureInfoTag() = default;
@@ -43,10 +140,9 @@ public:
const CDateTime& GetDateTimeTaken() const;
private:
static int TranslateString(const std::string &info);
- void GetStringFromArchive(CArchive &ar, char *string, size_t length);
- ExifInfo_t m_exifInfo;
- IPTCInfo_t m_iptcInfo;
+ ExifInfo m_exifInfo;
+ IPTCInfo m_iptcInfo;
bool m_isLoaded; // Set to true if metadata has been loaded from the picture file successfully
bool m_isInfoSetExternally; // Set to true if metadata has been set by an external call to SetInfo
CDateTime m_dateTimeTaken;
diff --git a/xbmc/platform/android/peripherals/AndroidJoystickState.h b/xbmc/platform/android/peripherals/AndroidJoystickState.h
index ee265f699f..0219a1b998 100644
--- a/xbmc/platform/android/peripherals/AndroidJoystickState.h
+++ b/xbmc/platform/android/peripherals/AndroidJoystickState.h
@@ -8,7 +8,7 @@
#pragma once
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
+#include "addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h"
#include "threads/CriticalSection.h"
#include <string>
diff --git a/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm b/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm
index 05257377f1..1075ab52c1 100644
--- a/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm
+++ b/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm
@@ -8,7 +8,7 @@
#import "Input_Gamecontroller.h"
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
+#include "addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h"
#include "threads/CriticalSection.h"
#include "threads/SingleLock.h"
#include "utils/log.h"
diff --git a/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.h b/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.h
index 083df0bcc6..b8f5bf2d5a 100644
--- a/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.h
+++ b/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.h
@@ -8,7 +8,7 @@
#pragma once
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
+#include "addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h"
#include "peripherals/PeripheralTypes.h"
#include "peripherals/bus/PeripheralBus.h"
#include "threads/CriticalSection.h"
diff --git a/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.mm b/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.mm
index aa1dd1d093..94410fb85f 100644
--- a/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.mm
+++ b/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbedded.mm
@@ -9,7 +9,7 @@
#include "PeripheralBusDarwinEmbedded.h"
#include "ServiceBroker.h"
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
+#include "addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h"
#include "peripherals/bus/PeripheralBus.h"
#include "peripherals/devices/PeripheralJoystick.h"
#include "threads/CriticalSection.h"
diff --git a/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbeddedManager.h b/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbeddedManager.h
index 2da6f32d24..2da2ef3765 100644
--- a/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbeddedManager.h
+++ b/xbmc/platform/darwin/ios-common/peripherals/PeripheralBusDarwinEmbeddedManager.h
@@ -6,7 +6,7 @@
* See LICENSES/README.md for more information.
*/
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
+#include "addons/kodi-dev-kit/include/kodi/addon-instance/peripheral/PeripheralUtils.h"
#include "peripherals/PeripheralTypes.h"
#include "threads/CriticalSection.h"
diff --git a/xbmc/platform/darwin/tvos/TVOSTopShelf.mm b/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
index 50dae8f508..71ac4518f5 100644
--- a/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
+++ b/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
@@ -53,85 +53,105 @@ void CTVOSTopShelf::SetTopShelfItems(CFileItemList& items, TVOSTopShelfItemsCate
@autoreleasepool
{
// Retrieve store URL
- auto storeUrl = [tvosShared getSharedURL];
- if (!storeUrl)
- return;
- storeUrl = [storeUrl URLByAppendingPathComponent:@"RA" isDirectory:YES];
-
- const auto isSandboxed = CDarwinEmbedUtils::IsIosSandboxed();
+ static const auto isSandboxed = CDarwinEmbedUtils::IsIosSandboxed();
+ static const auto storeUrl = [[tvosShared getSharedURL] URLByAppendingPathComponent:@"RA" isDirectory:YES];
CLog::Log(LOGDEBUG, "[TopShelf] (sandboxed: {}) Use storeUrl: {}", isSandboxed ? "yes" : "no",
storeUrl.path.UTF8String);
- // store all old thumbs in array
auto fileManager = NSFileManager.defaultManager;
- auto filePaths =
- [NSMutableSet setWithArray:[fileManager contentsOfDirectoryAtPath:storeUrl.path error:nil]];
- std::string raPath = storeUrl.path.UTF8String;
- // Shared dicts (if we are sandboxed we use sharedDefaults, else we use sharedJailbreak)
- auto sharedDefaults =
- isSandboxed ? [[NSUserDefaults alloc] initWithSuiteName:[tvosShared getSharedID]] : nil;
- auto sharedJailbreak = isSandboxed ? nil : [[NSMutableDictionary alloc] initWithCapacity:2];
+ // Retrieve TopShelf current categories
+ auto sharedSandboxDict = [[NSUserDefaults alloc] initWithSuiteName:[tvosShared getSharedID]];
+ static const auto topshelfKey = @"topshelfCategories";
+ static const auto sharedJailbreakUrl = [storeUrl URLByAppendingPathComponent:@"topshelf.dict"
+ isDirectory:NO];
+ NSMutableDictionary* topshelfCategories;
+ if (isSandboxed)
+ {
+ if ([sharedSandboxDict objectForKey:topshelfKey])
+ topshelfCategories = [[sharedSandboxDict objectForKey:topshelfKey] mutableCopy];
+ else
+ topshelfCategories = [NSMutableDictionary dictionaryWithCapacity:2];
+ }
+ else
+ {
+ if ([[NSFileManager defaultManager] fileExistsAtPath:sharedJailbreakUrl.path])
+ topshelfCategories = [NSMutableDictionary dictionaryWithContentsOfURL:sharedJailbreakUrl];
+ else
+ topshelfCategories = [NSMutableDictionary dictionaryWithCapacity:2];
+ }
- // Function used to add category items in TopShelf shared dict
+ // Function used to add category items in TopShelf dict
CVideoThumbLoader thumbLoader;
auto fillSharedDicts =
- [&](CFileItemList& items, NSString* categoryKey, uint32_t categoryTitleCode,
+ [&](CFileItemList& items, NSString* categoryKey, NSString* categoryTitle,
std::function<std::string(CFileItemPtr videoItem)> getThumbnailForItem,
std::function<std::string(CFileItemPtr videoItem)> getTitleForItem) {
+
+ // Store all old thumbs names of this category in array
+ const auto thumbsPath = [storeUrl URLByAppendingPathComponent:categoryKey isDirectory:YES];
+ auto thumbsToRemove = [NSMutableSet setWithArray:[fileManager contentsOfDirectoryAtPath:thumbsPath.path error:nil]];
+
if (items.Size() <= 0)
{
- // If there is no item in this category, remove this dict from sharedDefaults
- [sharedDefaults removeObjectForKey:categoryKey];
- return;
+ // If there is no item in this category, remove it from topshelfCategories
+ [topshelfCategories removeObjectForKey:categoryKey];
}
+ else
+ {
+ // Create dict for this category
+ auto categoryDict = [NSMutableDictionary dictionaryWithCapacity:2];
- // Create dict for this category
- auto categoryDict = [NSMutableDictionary dictionaryWithCapacity:2];
-
- // Save category title in dict
- categoryDict[@"categoryTitle"] = @(g_localizeStrings.Get(categoryTitleCode).c_str());
+ // Save category title in dict
+ categoryDict[@"categoryTitle"] = categoryTitle;
- // Create an array to store each category item
- const int categorySize = std::min(items.Size(), MaxItems);
- auto categoryItems = [NSMutableArray arrayWithCapacity:categorySize];
- for (int i = 0; i < categorySize; ++i)
- {
- @autoreleasepool
+ // Create an array to store each category item
+ const int categorySize = std::min(items.Size(), MaxItems);
+ auto categoryItems = [NSMutableArray arrayWithCapacity:categorySize];
+ for (int i = 0; i < categorySize; ++i)
{
- auto item = items.Get(i);
- if (!item->HasArt("thumb"))
- thumbLoader.LoadItem(item.get());
-
- auto thumbnailPath = getThumbnailForItem(item);
- auto fileName = std::to_string(item->GetVideoInfoTag()->m_iDbId) +
- URIUtils::GetFileName(thumbnailPath);
- auto destPath = URIUtils::AddFileToFolder(raPath, fileName);
- if (!XFILE::CFile::Exists(destPath))
- XFILE::CFile::Copy(thumbnailPath, destPath);
- else
+ @autoreleasepool
{
- // Remove from array so it doesn't get deleted at the end
- [filePaths removeObject:@(fileName.c_str())];
+ // Get item thumb and title
+ auto item = items.Get(i);
+ if (!item->HasArt("thumb"))
+ thumbLoader.LoadItem(item.get());
+
+ auto thumbPathSrc = getThumbnailForItem(item);
+ auto itemThumb = std::to_string(item->GetVideoInfoTag()->m_iDbId) +
+ URIUtils::GetFileName(thumbPathSrc);
+ auto thumbPathDst = URIUtils::AddFileToFolder(thumbsPath.path.UTF8String, itemThumb);
+ if (!XFILE::CFile::Exists(thumbPathDst))
+ XFILE::CFile::Copy(thumbPathSrc, thumbPathDst);
+ else
+ {
+ // Remove from thumbsToRemove array so it doesn't get deleted at the end
+ [thumbsToRemove removeObject:@(itemThumb.c_str())];
+ }
+
+ auto itemTitle = getTitleForItem(item);
+
+ // Add item object in categoryItems
+ CLog::Log(LOGDEBUG, "[TopShelf] Adding item '{}' in category '{}'", itemTitle.c_str(),
+ categoryKey.UTF8String);
+ [categoryItems addObject:@{
+ @"title" : @(itemTitle.c_str()),
+ @"thumb" : @(itemThumb.c_str()),
+ @"url" : @(Base64::Encode(item->GetVideoInfoTag()->GetPath()).c_str())
+ }];
}
-
- auto itemTitle = getTitleForItem(item);
- CLog::Log(LOGDEBUG, "[TopShelf] Adding item '{}' in category '{}'", itemTitle.c_str(),
- categoryKey.UTF8String);
- [categoryItems addObject:@{
- @"title" : @(itemTitle.c_str()),
- @"thumb" : @(fileName.c_str()),
- @"url" : @(Base64::Encode(item->GetVideoInfoTag()->GetPath()).c_str())
- }];
}
- }
- // Store category items array in category dict
- categoryDict[@"categoryItems"] = categoryItems;
+ // Store category items array in category dict
+ categoryDict[@"categoryItems"] = categoryItems;
- // Store category dict in shared dict
- [sharedDefaults setObject:categoryDict forKey:categoryKey];
- sharedJailbreak[categoryKey] = categoryDict;
+ // Store category dict in topshelfCategories
+ topshelfCategories[categoryKey] = categoryDict;
+ }
+
+ // Remove unused thumbs of this TopShelf category from thumbsPath folder
+ for (NSString* thumbFileName in thumbsToRemove)
+ [fileManager removeItemAtURL:[thumbsPath URLByAppendingPathComponent:thumbFileName isDirectory:NO] error:nil];
};
@@ -140,7 +160,7 @@ void CTVOSTopShelf::SetTopShelfItems(CFileItemList& items, TVOSTopShelfItemsCate
{
case TVOSTopShelfItemsCategory::MOVIES:
fillSharedDicts(
- items, @"movies", 20386,
+ items, @"movies", @(g_localizeStrings.Get(20386).c_str()),
[](CFileItemPtr videoItem) {
if (videoItem->HasArt("poster"))
return videoItem->GetArt("poster");
@@ -153,7 +173,7 @@ void CTVOSTopShelf::SetTopShelfItems(CFileItemList& items, TVOSTopShelfItemsCate
CVideoDatabase videoDb;
videoDb.Open();
fillSharedDicts(
- items, @"tvshows", 20387,
+ items, @"tvshows", @(g_localizeStrings.Get(20387).c_str()),
[&videoDb](CFileItemPtr videoItem) {
int season = videoItem->GetVideoInfoTag()->m_iIdSeason;
return season > 0 ? videoDb.GetArtForItem(season, MediaTypeSeason, "poster")
@@ -169,16 +189,14 @@ void CTVOSTopShelf::SetTopShelfItems(CFileItemList& items, TVOSTopShelfItemsCate
break;
}
- // Remove unused thumbs from cache folder
- NSString* strFiles;
- for (strFiles in filePaths)
- [fileManager removeItemAtURL:[storeUrl URLByAppendingPathComponent:strFiles isDirectory:NO]
- error:nil];
-
- // Synchronize shared dict
- [sharedDefaults synchronize];
- [sharedJailbreak writeToURL:[storeUrl URLByAppendingPathComponent:@"shared.dict"]
- atomically:YES];
+ // Set TopShelf new categories
+ if (isSandboxed)
+ {
+ [sharedSandboxDict setObject:topshelfCategories forKey:topshelfKey];
+ [sharedSandboxDict synchronize];
+ }
+ else
+ [topshelfCategories writeToURL:sharedJailbreakUrl atomically:YES];
}
}
diff --git a/xbmc/platform/darwin/tvos/TopShelf/ServiceProvider.mm b/xbmc/platform/darwin/tvos/TopShelf/ServiceProvider.mm
index fef201dfda..441aaa0615 100644
--- a/xbmc/platform/darwin/tvos/TopShelf/ServiceProvider.mm
+++ b/xbmc/platform/darwin/tvos/TopShelf/ServiceProvider.mm
@@ -36,30 +36,25 @@
- (NSArray<TVContentItem*>*)topShelfItems
{
// Retrieve store URL
- auto storeUrl = [tvosShared getSharedURL];
- if (!storeUrl)
- return @[];
- storeUrl = [storeUrl URLByAppendingPathComponent:@"RA" isDirectory:YES];
+ static const auto storeUrl = [[tvosShared getSharedURL] URLByAppendingPathComponent:@"RA" isDirectory:YES];
-
- // Retrieve shared dict
- NSDictionary* sharedDict;
- if (CDarwinEmbedUtils::IsIosSandboxed())
+ // Retrieve TopShelf categories
+ static const auto isSandboxed = CDarwinEmbedUtils::IsIosSandboxed();
+ NSDictionary* topshelfCategories;
+ if (isSandboxed)
{
- auto const sharedID = [tvosShared getSharedID];
- auto const shared = [[NSUserDefaults alloc] initWithSuiteName:sharedID];
- sharedDict = shared.dictionaryRepresentation;
+ auto sharedSandboxDict = [[NSUserDefaults alloc] initWithSuiteName:[tvosShared getSharedID]];
+ topshelfCategories = [sharedSandboxDict objectForKey:@"topshelfCategories"];
}
else
{
- auto sharedDictUrl = [storeUrl URLByAppendingPathComponent:@"shared.dict"
- isDirectory:NO];
- sharedDict = [NSDictionary dictionaryWithContentsOfFile:[sharedDictUrl path]];
+ static const auto sharedJailbreakUrl = [storeUrl URLByAppendingPathComponent:@"topshelf.dict"
+ isDirectory:NO];
+ topshelfCategories = [NSDictionary dictionaryWithContentsOfURL:sharedJailbreakUrl];
}
-
// Retrieve Kodi URL Scheme
- auto const mainAppBundle = [tvosShared mainAppBundle];
+ static auto const mainAppBundle = [tvosShared mainAppBundle];
auto kodiUrlScheme = @"kodi"; // fallback value
for (NSDictionary* dic in [mainAppBundle objectForInfoDictionaryKey:@"CFBundleURLTypes"])
{
@@ -73,19 +68,19 @@
auto wrapperIdentifier = [[TVContentIdentifier alloc] initWithIdentifier:@"shelf-wrapper"
container:nil];
-
// Function to create a TVContentItem array from an array of items (a category)
- auto contentItemsFrom = ^NSArray<TVContentItem*>*(NSArray* categoryItems)
+ auto contentItemsFrom = ^NSArray<TVContentItem*>*(NSString* categoryKey, NSArray* categoryItems)
{
NSMutableArray<TVContentItem*>* contentItems =
[[NSMutableArray alloc] initWithCapacity:categoryItems.count];
+ const auto thumbsPath = [storeUrl URLByAppendingPathComponent:categoryKey isDirectory:YES];
for (NSDictionary* item in categoryItems)
{
auto identifier = [[TVContentIdentifier alloc] initWithIdentifier:@"VOD"
container:wrapperIdentifier];
auto contentItem = [[TVContentItem alloc] initWithContentIdentifier:identifier];
- [contentItem setImageURL:[storeUrl URLByAppendingPathComponent:item[@"thumb"] isDirectory:NO]
+ [contentItem setImageURL:[thumbsPath URLByAppendingPathComponent:item[@"thumb"] isDirectory:NO]
forTraits:TVContentItemImageTraitScreenScale1x];
contentItem.imageShape = TVContentItemImageShapePoster;
contentItem.title = item[@"title"];
@@ -102,18 +97,10 @@
// Add each category to TopShelf
auto topShelfItems = [[NSMutableArray alloc] init];
- [sharedDict enumerateKeysAndObjectsUsingBlock:^(NSString* categoryKey, id categoryDict, BOOL *stop) {
- if (![categoryDict isKindOfClass:[NSDictionary class]])
- return;
- NSArray* categoryItems = categoryDict[@"categoryItems"];
- if (!categoryItems)
- return;
- if (categoryItems.count == 0)
- return;
-
+ [topshelfCategories enumerateKeysAndObjectsUsingBlock:^(NSString* categoryKey, NSDictionary* categoryDict, BOOL *stop) {
auto categoryContent = [[TVContentItem alloc] initWithContentIdentifier:wrapperIdentifier];
categoryContent.title = categoryDict[@"categoryTitle"];
- categoryContent.topShelfItems = contentItemsFrom(categoryItems);
+ categoryContent.topShelfItems = contentItemsFrom(categoryKey, categoryDict[@"categoryItems"]);
[topShelfItems addObject:categoryContent];
}];
diff --git a/xbmc/platform/linux/CMakeLists.txt b/xbmc/platform/linux/CMakeLists.txt
index 186c6dc7cc..3f851f521f 100644
--- a/xbmc/platform/linux/CMakeLists.txt
+++ b/xbmc/platform/linux/CMakeLists.txt
@@ -23,15 +23,4 @@ if(DBUS_FOUND)
DBusUtil.h)
endif()
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi)
- list(APPEND SOURCES RBP.cpp
- OMXCore.cpp
- ScreenshotSurfaceRBP.cpp)
- list(APPEND HEADERS RBP.h
- DllBCM.h
- DllOMX.h
- OMXCore.h
- ScreenshotSurfaceRBP.h)
-endif()
-
core_add_library(linuxsupport)
diff --git a/xbmc/platform/linux/DllBCM.h b/xbmc/platform/linux/DllBCM.h
deleted file mode 100644
index e04bf0e99e..0000000000
--- a/xbmc/platform/linux/DllBCM.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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
-
-#ifndef __GNUC__
-#pragma warning(push)
-#pragma warning(disable:4244)
-#endif
-
-extern "C" {
-#include <bcm_host.h>
-}
-
-#include "DynamicDll.h"
-#include "utils/log.h"
-
-#define USE_EXTERNAL_LIBBCM_HOST 1
-
-////////////////////////////////////////////////////////////////////////////////////////////
-
-class DllBcmHostInterface
-{
-public:
- virtual ~DllBcmHostInterface() {}
-
- virtual void bcm_host_init() = 0;
- virtual void bcm_host_deinit() = 0;
- virtual int32_t graphics_get_display_size( const uint16_t display_number, uint32_t *width, uint32_t *height) = 0;
- virtual int vc_tv_power_off() = 0;
- virtual int vc_tv_sdtv_power_on(SDTV_MODE_T mode, SDTV_OPTIONS_T *options) = 0;
- virtual int vc_tv_hdmi_power_on_preferred() = 0;
- virtual int vc_tv_hdmi_power_on_best(uint32_t width, uint32_t height, uint32_t frame_rate,
- HDMI_INTERLACED_T scan_mode, EDID_MODE_MATCH_FLAG_T match_flags) = 0;
- virtual int vc_tv_hdmi_power_on_best_3d(uint32_t width, uint32_t height, uint32_t frame_rate,
- HDMI_INTERLACED_T scan_mode, EDID_MODE_MATCH_FLAG_T match_flags) = 0;
-
- virtual int vc_tv_hdmi_get_supported_modes_new(HDMI_RES_GROUP_T group, TV_SUPPORTED_MODE_NEW_T *supported_modes,
- uint32_t max_supported_modes, HDMI_RES_GROUP_T *preferred_group,
- uint32_t *preferred_mode) = 0;
- virtual int vc_tv_hdmi_power_on_explicit_new(HDMI_MODE_T mode, HDMI_RES_GROUP_T group, uint32_t code) = 0;
- virtual int vc_tv_hdmi_set_property(const HDMI_PROPERTY_PARAM_T *property) = 0;
- virtual int vc_tv_get_display_state(TV_DISPLAY_STATE_T *tvstate) = 0;
- virtual int vc_tv_show_info(uint32_t show) = 0;
- virtual int vc_gencmd(char *response, int maxlen, const char *string) = 0;
- virtual void vc_tv_register_callback(TVSERVICE_CALLBACK_T callback, void *callback_data) = 0;
- virtual void vc_tv_unregister_callback(TVSERVICE_CALLBACK_T callback) = 0;
- virtual void vc_cec_register_callback(CECSERVICE_CALLBACK_T callback, void *callback_data) = 0;
- //virtual void vc_cec_unregister_callback(CECSERVICE_CALLBACK_T callback) = 0;
- virtual DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open( uint32_t device ) = 0;
- virtual DISPMANX_UPDATE_HANDLE_T vc_dispmanx_update_start( int32_t priority ) = 0;
- virtual DISPMANX_ELEMENT_HANDLE_T vc_dispmanx_element_add ( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display,
- int32_t layer, const VC_RECT_T *dest_rect, DISPMANX_RESOURCE_HANDLE_T src,
- const VC_RECT_T *src_rect, DISPMANX_PROTECTION_T protection,
- VC_DISPMANX_ALPHA_T *alpha,
- DISPMANX_CLAMP_T *clamp, DISPMANX_TRANSFORM_T transform ) = 0;
- virtual int vc_dispmanx_update_submit_sync( DISPMANX_UPDATE_HANDLE_T update ) = 0;
- virtual int vc_dispmanx_update_submit( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg ) = 0;
-
- virtual int vc_dispmanx_element_remove( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element ) = 0;
- virtual int vc_dispmanx_element_change_attributes( DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_ELEMENT_HANDLE_T element,
- uint32_t change_flags,
- int32_t layer,
- uint8_t opacity,
- const VC_RECT_T *dest_rect,
- const VC_RECT_T *src_rect,
- DISPMANX_RESOURCE_HANDLE_T mask,
- DISPMANX_TRANSFORM_T transform ) = 0;
- virtual int vc_dispmanx_display_close( DISPMANX_DISPLAY_HANDLE_T display ) = 0;
- virtual int vc_dispmanx_display_get_info( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_MODEINFO_T * pinfo ) = 0;
- virtual int vc_dispmanx_display_set_background( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display,
- uint8_t red, uint8_t green, uint8_t blue ) = 0;
- virtual int vc_tv_hdmi_audio_supported(uint32_t audio_format, uint32_t num_channels,
- EDID_AudioSampleRate fs, uint32_t bitrate) = 0;
-};
-
-#if defined(USE_EXTERNAL_LIBBCM_HOST)
-class DllBcmHost : public DllDynamic, DllBcmHostInterface
-{
-public:
- virtual void bcm_host_init()
- { return ::bcm_host_init(); };
- virtual void bcm_host_deinit()
- { return ::bcm_host_deinit(); };
- virtual int32_t graphics_get_display_size( const uint16_t display_number, uint32_t *width, uint32_t *height)
- { return ::graphics_get_display_size(display_number, width, height); };
- virtual int vc_tv_power_off()
- { return ::vc_tv_power_off(); }
- virtual int vc_tv_sdtv_power_on(SDTV_MODE_T mode, SDTV_OPTIONS_T *options)
- { return ::vc_tv_sdtv_power_on(mode, options); }
- virtual int vc_tv_hdmi_power_on_preferred()
- { return ::vc_tv_hdmi_power_on_preferred(); }
- virtual int vc_tv_hdmi_power_on_best(uint32_t width, uint32_t height, uint32_t frame_rate,
- HDMI_INTERLACED_T scan_mode, EDID_MODE_MATCH_FLAG_T match_flags)
- { return ::vc_tv_hdmi_power_on_best(width, height, frame_rate, scan_mode, match_flags); };
- virtual int vc_tv_hdmi_power_on_best_3d(uint32_t width, uint32_t height, uint32_t frame_rate,
- HDMI_INTERLACED_T scan_mode, EDID_MODE_MATCH_FLAG_T match_flags)
- { return ::vc_tv_hdmi_power_on_best_3d(width, height, frame_rate, scan_mode, match_flags); };
- virtual int vc_tv_hdmi_get_supported_modes_new(HDMI_RES_GROUP_T group, TV_SUPPORTED_MODE_NEW_T *supported_modes,
- uint32_t max_supported_modes, HDMI_RES_GROUP_T *preferred_group,
- uint32_t *preferred_mode)
- { return ::vc_tv_hdmi_get_supported_modes_new(group, supported_modes, max_supported_modes, preferred_group, preferred_mode); };
- virtual int vc_tv_hdmi_power_on_explicit_new(HDMI_MODE_T mode, HDMI_RES_GROUP_T group, uint32_t code)
- { return ::vc_tv_hdmi_power_on_explicit_new(mode, group, code); };
- virtual int vc_tv_hdmi_set_property(const HDMI_PROPERTY_PARAM_T *property)
- { return ::vc_tv_hdmi_set_property(property); };
- virtual int vc_tv_get_display_state(TV_DISPLAY_STATE_T *tvstate)
- { return ::vc_tv_get_display_state(tvstate); };
- virtual int vc_tv_show_info(uint32_t show)
- { return ::vc_tv_show_info(show); };
- virtual int vc_gencmd(char *response, int maxlen, const char *string)
- { return ::vc_gencmd(response, maxlen, string); };
- virtual void vc_tv_register_callback(TVSERVICE_CALLBACK_T callback, void *callback_data)
- { ::vc_tv_register_callback(callback, callback_data); };
- virtual void vc_tv_unregister_callback(TVSERVICE_CALLBACK_T callback)
- { ::vc_tv_unregister_callback(callback); };
- virtual void vc_cec_register_callback(CECSERVICE_CALLBACK_T callback, void *callback_data)
- { ::vc_cec_register_callback(callback, callback_data); };
- //virtual void vc_cec_unregister_callback(CECSERVICE_CALLBACK_T callback)
- // { ::vc_cec_unregister_callback(callback); };
- virtual DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open( uint32_t device )
- { return ::vc_dispmanx_display_open(device); };
- virtual DISPMANX_UPDATE_HANDLE_T vc_dispmanx_update_start( int32_t priority )
- { return ::vc_dispmanx_update_start(priority); };
- virtual DISPMANX_ELEMENT_HANDLE_T vc_dispmanx_element_add ( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display,
- int32_t layer, const VC_RECT_T *dest_rect, DISPMANX_RESOURCE_HANDLE_T src,
- const VC_RECT_T *src_rect, DISPMANX_PROTECTION_T protection,
- VC_DISPMANX_ALPHA_T *alpha,
- DISPMANX_CLAMP_T *clamp, DISPMANX_TRANSFORM_T transform )
- { return ::vc_dispmanx_element_add(update, display, layer, dest_rect, src, src_rect, protection, alpha, clamp, transform); };
- virtual int vc_dispmanx_update_submit_sync( DISPMANX_UPDATE_HANDLE_T update )
- { return ::vc_dispmanx_update_submit_sync(update); };
- virtual int vc_dispmanx_update_submit( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg )
- { return ::vc_dispmanx_update_submit(update, cb_func, cb_arg); };
- virtual int vc_dispmanx_element_remove( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element )
- { return ::vc_dispmanx_element_remove(update, element); };
- virtual int vc_dispmanx_element_change_attributes( DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_ELEMENT_HANDLE_T element,
- uint32_t change_flags,
- int32_t layer,
- uint8_t opacity,
- const VC_RECT_T *dest_rect,
- const VC_RECT_T *src_rect,
- DISPMANX_RESOURCE_HANDLE_T mask,
- DISPMANX_TRANSFORM_T transform )
- { return ::vc_dispmanx_element_change_attributes( update, element, change_flags, layer, opacity, dest_rect, src_rect, mask, transform ); };
- virtual int vc_dispmanx_display_close( DISPMANX_DISPLAY_HANDLE_T display )
- { return ::vc_dispmanx_display_close(display); };
- virtual int vc_dispmanx_display_get_info( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_MODEINFO_T *pinfo )
- { return ::vc_dispmanx_display_get_info(display, pinfo); };
- virtual int vc_dispmanx_display_set_background( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display,
- uint8_t red, uint8_t green, uint8_t blue )
- { return ::vc_dispmanx_display_set_background(update, display, red, green, blue); };
- virtual int vc_tv_hdmi_audio_supported(uint32_t audio_format, uint32_t num_channels,
- EDID_AudioSampleRate fs, uint32_t bitrate)
- { return ::vc_tv_hdmi_audio_supported(audio_format, num_channels, fs, bitrate); };
- virtual bool ResolveExports()
- { return true; }
- virtual bool Load()
- {
- CLog::Log(LOGDEBUG, "DllBcm: Using omx system library");
- return true;
- }
- virtual void Unload() {}
-};
-#else
-class DllBcmHost : public DllDynamic, DllBcmHostInterface
-{
- DECLARE_DLL_WRAPPER(DllBcmHost, "/opt/vc/lib/libbcm_host.so")
-
- DEFINE_METHOD0(void, bcm_host_init)
- DEFINE_METHOD0(void, bcm_host_deinit)
- DEFINE_METHOD3(int32_t, graphics_get_display_size, (const uint16_t p1, uint32_t *p2, uint32_t *p3))
- DEFINE_METHOD5(int, vc_tv_hdmi_power_on_best, (uint32_t p1, uint32_t p2, uint32_t p3,
- HDMI_INTERLACED_T p4, EDID_MODE_MATCH_FLAG_T p5))
- DEFINE_METHOD5(int, vc_tv_hdmi_power_on_best_3d, (uint32_t p1, uint32_t p2, uint32_t p3,
- HDMI_INTERLACED_T p4, EDID_MODE_MATCH_FLAG_T p5))
- DEFINE_METHOD5(int, vc_tv_hdmi_get_supported_modes_new, (HDMI_RES_GROUP_T p1, TV_SUPPORTED_MODE_NEW_T *p2,
- uint32_t p3, HDMI_RES_GROUP_T *p4, uint32_t *p5))
- DEFINE_METHOD3(int, vc_tv_hdmi_power_on_explicit_new, (HDMI_MODE_T p1, HDMI_RES_GROUP_T p2, uint32_t p3))
- DEFINE_METHOD1(int, vc_tv_hdmi_set_property, (const HDMI_PROPERTY_PARAM_T *property))
- DEFINE_METHOD1(int, vc_tv_get_display_state, (TV_DISPLAY_STATE_T *p1))
- DEFINE_METHOD1(int, vc_tv_show_info, (uint32_t p1))
- DEFINE_METHOD3(int, vc_gencmd, (char *p1, int p2, const char *p3))
-
- DEFINE_METHOD2(void, vc_tv_register_callback, (TVSERVICE_CALLBACK_T p1, void *p2))
- DEFINE_METHOD1(void, vc_tv_unregister_callback, (TVSERVICE_CALLBACK_T p1))
-
- DEFINE_METHOD2(void, vc_cec_register_callback, (CECSERVICE_CALLBACK_T p1, void *p2))
- //DEFINE_METHOD1(void, vc_cec_unregister_callback, (CECSERVICE_CALLBACK_T p1))
- DEFINE_METHOD1(DISPMANX_DISPLAY_HANDLE_T, vc_dispmanx_display_open, (uint32_t p1 ))
- DEFINE_METHOD1(DISPMANX_UPDATE_HANDLE_T, vc_dispmanx_update_start, (int32_t p1 ))
- DEFINE_METHOD10(DISPMANX_ELEMENT_HANDLE_T, vc_dispmanx_element_add, (DISPMANX_UPDATE_HANDLE_T p1, DISPMANX_DISPLAY_HANDLE_T p2,
- int32_t p3, const VC_RECT_T *p4, DISPMANX_RESOURCE_HANDLE_T p5,
- const VC_RECT_T *p6, DISPMANX_PROTECTION_T p7,
- VC_DISPMANX_ALPHA_T *p8,
- DISPMANX_CLAMP_T *p9, DISPMANX_TRANSFORM_T p10 ))
- DEFINE_METHOD1(int, vc_dispmanx_update_submit_sync, (DISPMANX_UPDATE_HANDLE_T p1))
- DEFINE_METHOD3(int, vc_dispmanx_update_submit, (DISPMANX_UPDATE_HANDLE_T p1, DISPMANX_CALLBACK_FUNC_T p2, void *p3))
- DEFINE_METHOD2(int, vc_dispmanx_element_remove, (DISPMANX_UPDATE_HANDLE_T p1, DISPMANX_ELEMENT_HANDLE_T p2))
- DEFINE_METHOD9(int, vc_dispmanx_element_change_attributes, ( DISPMANX_UPDATE_HANDLE_T p1,
- DISPMANX_ELEMENT_HANDLE_T p2,
- uint32_t p3,
- int32_t p4,
- uint8_t p5,
- const VC_RECT_T *p6,
- const VC_RECT_T *p7rect,
- DISPMANX_RESOURCE_HANDLE_T p8,
- DISPMANX_TRANSFORM_T p9))
- DEFINE_METHOD1(int, vc_dispmanx_display_close, (DISPMANX_DISPLAY_HANDLE_T p1))
- DEFINE_METHOD2(int, vc_dispmanx_display_get_info, (DISPMANX_DISPLAY_HANDLE_T p1, DISPMANX_MODEINFO_T *p2))
- DEFINE_METHOD5(int, vc_dispmanx_display_set_background, ( DISPMANX_UPDATE_HANDLE_T p1, DISPMANX_DISPLAY_HANDLE_T p2,
- uint8_t p3, uint8_t p4, uint8_t p5 ))
- DEFINE_METHOD4(int, vc_tv_hdmi_audio_supported, (uint32_t p1, uint32_t p2, EDID_AudioSampleRate p3, uint32_t p4))
-
- BEGIN_METHOD_RESOLVE()
- RESOLVE_METHOD(bcm_host_init)
- RESOLVE_METHOD(bcm_host_deinit)
- RESOLVE_METHOD(graphics_get_display_size)
- RESOLVE_METHOD(vc_tv_hdmi_power_on_best)
- RESOLVE_METHOD(vc_tv_hdmi_power_on_best_3d)
- RESOLVE_METHOD(vc_tv_hdmi_get_supported_modes_new)
- RESOLVE_METHOD(vc_tv_hdmi_power_on_explicit_new)
- RESOLVE_METHOD(vc_tv_hdmi_set_property)
- RESOLVE_METHOD(vc_tv_get_display_state)
- RESOLVE_METHOD(vc_tv_show_info)
- RESOLVE_METHOD(vc_gencmd)
- RESOLVE_METHOD(vc_tv_register_callback)
- RESOLVE_METHOD(vc_tv_unregister_callback)
- RESOLVE_METHOD(vc_cec_register_callback)
- //RESOLVE_METHOD(vc_cec_unregister_callback)
- RESOLVE_METHOD(vc_dispmanx_display_open)
- RESOLVE_METHOD(vc_dispmanx_update_start)
- RESOLVE_METHOD(vc_dispmanx_element_add)
- RESOLVE_METHOD(vc_dispmanx_update_submit_sync)
- RESOLVE_METHOD(vc_dispmanx_update_submit)
- RESOLVE_METHOD(vc_dispmanx_element_remove)
- RESOLVE_METHOD(vc_dispmanx_element_change_attributes)
- RESOLVE_METHOD(vc_dispmanx_display_close)
- RESOLVE_METHOD(vc_dispmanx_display_get_info)
- RESOLVE_METHOD(vc_dispmanx_display_set_background)
- RESOLVE_METHOD(vc_tv_hdmi_audio_supported)
- END_METHOD_RESOLVE()
-
-public:
- virtual bool Load()
- {
- return DllDynamic::Load();
- }
-};
-#endif
diff --git a/xbmc/platform/linux/DllOMX.h b/xbmc/platform/linux/DllOMX.h
deleted file mode 100644
index 7643796827..0000000000
--- a/xbmc/platform/linux/DllOMX.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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
-
-#ifndef __GNUC__
-#pragma warning(push)
-#pragma warning(disable:4244)
-#endif
-
-#include "DynamicDll.h"
-#include "utils/log.h"
-
-#include <IL/OMX_Core.h>
-#include <IL/OMX_Component.h>
-#include <IL/OMX_Index.h>
-#include <IL/OMX_Image.h>
-#include <IL/OMX_Video.h>
-#include <IL/OMX_Broadcom.h>
-
-////////////////////////////////////////////////////////////////////////////////////////////
-
-class DllOMXInterface
-{
-public:
- virtual ~DllOMXInterface() {}
-
- virtual OMX_ERRORTYPE OMX_Init(void) = 0;
- virtual OMX_ERRORTYPE OMX_Deinit(void) = 0;
- virtual OMX_ERRORTYPE OMX_GetHandle(OMX_HANDLETYPE *pHandle, OMX_STRING cComponentName, OMX_PTR pAppData, OMX_CALLBACKTYPE *pCallBacks) = 0;
- virtual OMX_ERRORTYPE OMX_FreeHandle(OMX_HANDLETYPE hComponent) = 0;
- virtual OMX_ERRORTYPE OMX_GetComponentsOfRole(OMX_STRING role, OMX_U32 *pNumComps, OMX_U8 **compNames) = 0;
- virtual OMX_ERRORTYPE OMX_GetRolesOfComponent(OMX_STRING compName, OMX_U32 *pNumRoles, OMX_U8 **roles) = 0;
- virtual OMX_ERRORTYPE OMX_ComponentNameEnum(OMX_STRING cComponentName, OMX_U32 nNameLength, OMX_U32 nIndex) = 0;
- virtual OMX_ERRORTYPE OMX_SetupTunnel(OMX_HANDLETYPE hOutput, OMX_U32 nPortOutput, OMX_HANDLETYPE hInput, OMX_U32 nPortInput) = 0;
-
-};
-
-#if (defined USE_EXTERNAL_OMX)
-class DllOMX : public DllDynamic, DllOMXInterface
-{
-public:
- virtual OMX_ERRORTYPE OMX_Init(void)
- { return ::OMX_Init(); };
- virtual OMX_ERRORTYPE OMX_Deinit(void)
- { return ::OMX_Deinit(); };
- virtual OMX_ERRORTYPE OMX_GetHandle(OMX_HANDLETYPE *pHandle, OMX_STRING cComponentName, OMX_PTR pAppData, OMX_CALLBACKTYPE *pCallBacks)
- { return ::OMX_GetHandle(pHandle, cComponentName, pAppData, pCallBacks); };
- virtual OMX_ERRORTYPE OMX_FreeHandle(OMX_HANDLETYPE hComponent)
- { return ::OMX_FreeHandle(hComponent); };
- virtual OMX_ERRORTYPE OMX_GetComponentsOfRole(OMX_STRING role, OMX_U32 *pNumComps, OMX_U8 **compNames)
- { return ::OMX_GetComponentsOfRole(role, pNumComps, compNames); };
- virtual OMX_ERRORTYPE OMX_GetRolesOfComponent(OMX_STRING compName, OMX_U32 *pNumRoles, OMX_U8 **roles)
- { return ::OMX_GetRolesOfComponent(compName, pNumRoles, roles); };
- virtual OMX_ERRORTYPE OMX_ComponentNameEnum(OMX_STRING cComponentName, OMX_U32 nNameLength, OMX_U32 nIndex)
- { return ::OMX_ComponentNameEnum(cComponentName, nNameLength, nIndex); };
- virtual OMX_ERRORTYPE OMX_SetupTunnel(OMX_HANDLETYPE hOutput, OMX_U32 nPortOutput, OMX_HANDLETYPE hInput, OMX_U32 nPortInput)
- { return ::OMX_SetupTunnel(hOutput, nPortOutput, hInput, nPortInput); };
- virtual bool ResolveExports()
- { return true; }
- virtual bool Load()
- {
- CLog::Log(LOGDEBUG, "DllOMX: Using omx system library");
- return true;
- }
- virtual void Unload() {}
-};
-#else
-class DllOMX : public DllDynamic, DllOMXInterface
-{
- DECLARE_DLL_WRAPPER(DllOMX, "libopenmaxil.so")
-
- DEFINE_METHOD0(OMX_ERRORTYPE, OMX_Init)
- DEFINE_METHOD0(OMX_ERRORTYPE, OMX_Deinit)
- DEFINE_METHOD4(OMX_ERRORTYPE, OMX_GetHandle, (OMX_HANDLETYPE *p1, OMX_STRING p2, OMX_PTR p3, OMX_CALLBACKTYPE *p4))
- DEFINE_METHOD1(OMX_ERRORTYPE, OMX_FreeHandle, (OMX_HANDLETYPE p1))
- DEFINE_METHOD3(OMX_ERRORTYPE, OMX_GetComponentsOfRole, (OMX_STRING p1, OMX_U32 *p2, OMX_U8 **p3))
- DEFINE_METHOD3(OMX_ERRORTYPE, OMX_GetRolesOfComponent, (OMX_STRING p1, OMX_U32 *p2, OMX_U8 **p3))
- DEFINE_METHOD3(OMX_ERRORTYPE, OMX_ComponentNameEnum, (OMX_STRING p1, OMX_U32 p2, OMX_U32 p3))
- DEFINE_METHOD4(OMX_ERRORTYPE, OMX_SetupTunnel, (OMX_HANDLETYPE p1, OMX_U32 p2, OMX_HANDLETYPE p3, OMX_U32 p4));
- BEGIN_METHOD_RESOLVE()
- RESOLVE_METHOD(OMX_Init)
- RESOLVE_METHOD(OMX_Deinit)
- RESOLVE_METHOD(OMX_GetHandle)
- RESOLVE_METHOD(OMX_FreeHandle)
- RESOLVE_METHOD(OMX_GetComponentsOfRole)
- RESOLVE_METHOD(OMX_GetRolesOfComponent)
- RESOLVE_METHOD(OMX_ComponentNameEnum)
- RESOLVE_METHOD(OMX_SetupTunnel)
- END_METHOD_RESOLVE()
-
-public:
- virtual bool Load()
- {
- return DllDynamic::Load();
- }
-};
-#endif
diff --git a/xbmc/platform/linux/OMXCore.cpp b/xbmc/platform/linux/OMXCore.cpp
deleted file mode 100644
index b2eb3acf45..0000000000
--- a/xbmc/platform/linux/OMXCore.cpp
+++ /dev/null
@@ -1,1792 +0,0 @@
-/*
- * Copyright (C) 2010-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "OMXCore.h"
-
-#include "utils/log.h"
-
-#include "platform/linux/RBP.h"
-
-#include <cassert>
-#include <math.h>
-
-#include <sys/time.h>
-
-//#define OMX_DEBUG_EVENTS
-//#define OMX_DEBUG_EVENTHANDLER
-
-////////////////////////////////////////////////////////////////////////////////////////////
-#define CLASSNAME "COMXCoreComponent"
-////////////////////////////////////////////////////////////////////////////////////////////
-
-static void add_timespecs(struct timespec &time, long millisecs)
-{
- long long nsec = time.tv_nsec + (long long)millisecs * 1000000;
- while (nsec > 1000000000)
- {
- time.tv_sec += 1;
- nsec -= 1000000000;
- }
- time.tv_nsec = nsec;
-}
-
-
-COMXCoreTunnel::COMXCoreTunnel()
-{
- m_src_component = NULL;
- m_dst_component = NULL;
- m_src_port = 0;
- m_dst_port = 0;
- m_tunnel_set = false;
- m_DllOMX = g_RBP.GetDllOMX();
-}
-
-COMXCoreTunnel::~COMXCoreTunnel()
-{
-}
-
-void COMXCoreTunnel::Initialize(COMXCoreComponent *src_component, unsigned int src_port, COMXCoreComponent *dst_component, unsigned int dst_port)
-{
- m_src_component = src_component;
- m_src_port = src_port;
- m_dst_component = dst_component;
- m_dst_port = dst_port;
-}
-
-OMX_ERRORTYPE COMXCoreTunnel::Deestablish(bool noWait)
-{
- if(!m_src_component || !m_dst_component || !IsInitialized())
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if(m_src_component->GetComponent())
- {
- omx_err = m_src_component->DisablePort(m_src_port, false);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Deestablish - Error disable port %d on component %s omx_err(0x%08x)",
- m_src_port, m_src_component->GetName().c_str(), (int)omx_err);
- }
- }
-
- if(m_dst_component->GetComponent())
- {
- omx_err = m_dst_component->DisablePort(m_dst_port, false);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Deestablish - Error disable port %d on component %s omx_err(0x%08x)",
- m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
- }
- }
-
- if(m_src_component->GetComponent())
- {
- omx_err = m_src_component->WaitForCommand(OMX_CommandPortDisable, m_src_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Deestablish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
- m_dst_port, m_src_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
-
- if(m_dst_component->GetComponent())
- {
- omx_err = m_dst_component->WaitForCommand(OMX_CommandPortDisable, m_dst_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Deestablish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
- m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
-
- if(m_src_component->GetComponent())
- {
- omx_err = m_DllOMX->OMX_SetupTunnel(m_src_component->GetComponent(), m_src_port, NULL, 0);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreTunnel::Deestablish - could not unset tunnel on comp src %s port %d "
- "omx_err(0x%08x)",
- m_src_component->GetName().c_str(), m_src_port, (int)omx_err);
- }
- }
-
- if(m_dst_component->GetComponent())
- {
- omx_err = m_DllOMX->OMX_SetupTunnel(m_dst_component->GetComponent(), m_dst_port, NULL, 0);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreTunnel::Deestablish - could not unset tunnel on comp dst %s port %d "
- "omx_err(0x%08x)",
- m_dst_component->GetName().c_str(), m_dst_port, (int)omx_err);
- }
- }
-
- m_tunnel_set = false;
-
- return OMX_ErrorNone;
-}
-
-OMX_ERRORTYPE COMXCoreTunnel::Establish(bool enable_ports /* = true */, bool disable_ports /* = false */)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- OMX_PARAM_U32TYPE param;
- OMX_INIT_STRUCTURE(param);
-
- if(!m_src_component || !m_dst_component)
- {
- return OMX_ErrorUndefined;
- }
-
- if(m_src_component->GetState() == OMX_StateLoaded)
- {
- omx_err = m_src_component->SetStateForComponent(OMX_StateIdle);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - Error setting state to idle %s omx_err(0x%08x)",
- m_src_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
-
- if(m_src_component->GetComponent() && disable_ports)
- {
- omx_err = m_src_component->DisablePort(m_src_port, false);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - Error disable port %d on component %s omx_err(0x%08x)",
- m_src_port, m_src_component->GetName().c_str(), (int)omx_err);
- }
- }
-
- if(m_dst_component->GetComponent() && disable_ports)
- {
- omx_err = m_dst_component->DisablePort(m_dst_port, false);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - Error disable port %d on component %s omx_err(0x%08x)",
- m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
- }
- }
-
- if(m_src_component->GetComponent() && disable_ports)
- {
- omx_err = m_src_component->WaitForCommand(OMX_CommandPortDisable, m_src_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
- m_dst_port, m_src_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
-
- if(m_dst_component->GetComponent() && disable_ports)
- {
- omx_err = m_dst_component->WaitForCommand(OMX_CommandPortDisable, m_dst_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
- m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
-
- if(m_src_component->GetComponent() && m_dst_component->GetComponent())
- {
- omx_err = m_DllOMX->OMX_SetupTunnel(m_src_component->GetComponent(), m_src_port, m_dst_component->GetComponent(), m_dst_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreTunnel::Establish - could not setup tunnel src %s port %d dst %s port %d "
- "omx_err(0x%08x)",
- m_src_component->GetName().c_str(), m_src_port, m_dst_component->GetName().c_str(),
- m_dst_port, (int)omx_err);
- return omx_err;
- }
- }
- else
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - could not setup tunnel");
- return OMX_ErrorUndefined;
- }
-
- m_tunnel_set = true;
-
- if(m_src_component->GetComponent() && enable_ports)
- {
- omx_err = m_src_component->EnablePort(m_src_port, false);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - Error enable port %d on component %s omx_err(0x%08x)",
- m_src_port, m_src_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
-
- if(m_dst_component->GetComponent() && enable_ports)
- {
- omx_err = m_dst_component->EnablePort(m_dst_port, false);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreTunnel::Establish - Error enable port %d on component %s omx_err(0x%08x)",
- m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
-
- if(m_dst_component->GetComponent() && enable_ports)
- {
- omx_err = m_dst_component->WaitForCommand(OMX_CommandPortEnable, m_dst_port);
- if(omx_err != OMX_ErrorNone)
- {
- return omx_err;
- }
-
- if(m_dst_component->GetState() == OMX_StateLoaded)
- {
- omx_err = m_dst_component->SetStateForComponent(OMX_StateIdle);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::Establish - Error setting state to idle %s omx_err(0x%08x)",
- m_src_component->GetName().c_str(), (int)omx_err);
- return omx_err;
- }
- }
- }
-
- if(m_src_component->GetComponent() && enable_ports)
- {
- omx_err = m_src_component->WaitForCommand(OMX_CommandPortEnable, m_src_port);
- if(omx_err != OMX_ErrorNone)
- {
- return omx_err;
- }
- }
-
- return OMX_ErrorNone;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////
-
-COMXCoreComponent::COMXCoreComponent()
-{
- m_input_port = 0;
- m_output_port = 0;
- m_handle = NULL;
-
- m_input_alignment = 0;
- m_input_buffer_size = 0;
- m_input_buffer_count = 0;
-
- m_output_alignment = 0;
- m_output_buffer_size = 0;
- m_output_buffer_count = 0;
- m_flush_input = false;
- m_flush_output = false;
- m_resource_error = false;
-
- m_eos = false;
-
- m_exit = false;
-
- m_omx_events.clear();
- m_ignore_error = OMX_ErrorNone;
-
- pthread_mutex_init(&m_omx_input_mutex, NULL);
- pthread_mutex_init(&m_omx_output_mutex, NULL);
- pthread_mutex_init(&m_omx_event_mutex, NULL);
- pthread_mutex_init(&m_omx_eos_mutex, NULL);
- pthread_cond_init(&m_input_buffer_cond, NULL);
- pthread_cond_init(&m_output_buffer_cond, NULL);
- pthread_cond_init(&m_omx_event_cond, NULL);
-
- m_DllOMX = g_RBP.GetDllOMX();
-}
-
-COMXCoreComponent::~COMXCoreComponent()
-{
- Deinitialize();
-
- pthread_mutex_destroy(&m_omx_input_mutex);
- pthread_mutex_destroy(&m_omx_output_mutex);
- pthread_mutex_destroy(&m_omx_event_mutex);
- pthread_mutex_destroy(&m_omx_eos_mutex);
- pthread_cond_destroy(&m_input_buffer_cond);
- pthread_cond_destroy(&m_output_buffer_cond);
- pthread_cond_destroy(&m_omx_event_cond);
-}
-
-void COMXCoreComponent::TransitionToStateLoaded()
-{
- if(!m_handle)
- return;
-
- if(GetState() != OMX_StateLoaded && GetState() != OMX_StateIdle)
- SetStateForComponent(OMX_StateIdle);
-
- if(GetState() != OMX_StateLoaded)
- SetStateForComponent(OMX_StateLoaded);
-}
-
-OMX_ERRORTYPE COMXCoreComponent::EmptyThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "COMXCoreComponent::EmptyThisBuffer component(%s) %p",
- m_componentName.c_str(), omx_buffer);
-#endif
- if(!m_handle || !omx_buffer)
- return OMX_ErrorUndefined;
-
- omx_err = OMX_EmptyThisBuffer(m_handle, omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::EmptyThisBuffer component(%s) - failed with result(0x%x)",
- m_componentName.c_str(), omx_err);
- }
-
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::FillThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "COMXCoreComponent::FillThisBuffer component(%s) %p", m_componentName.c_str(),
- omx_buffer);
-#endif
- if(!m_handle || !omx_buffer)
- return OMX_ErrorUndefined;
-
- omx_err = OMX_FillThisBuffer(m_handle, omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::FillThisBuffer component(%s) - failed with result(0x%x)",
- m_componentName.c_str(), omx_err);
- }
-
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::FreeOutputBuffer(OMX_BUFFERHEADERTYPE *omx_buffer)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if(!m_handle || !omx_buffer)
- return OMX_ErrorUndefined;
-
- omx_err = OMX_FreeBuffer(m_handle, m_output_port, omx_buffer);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::FreeOutputBuffer component(%s) - failed with result(0x%x)",
- m_componentName.c_str(), omx_err);
- }
-
- return omx_err;
-}
-
-void COMXCoreComponent::FlushAll()
-{
- FlushInput();
- FlushOutput();
-}
-
-void COMXCoreComponent::FlushInput()
-{
- if(!m_handle || m_resource_error)
- return;
-
- OMX_ERRORTYPE omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_input_port, NULL);
-
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::FlushInput - Error on component %s omx_err(0x%08x)",
- m_componentName.c_str(), (int)omx_err);
- }
- WaitForCommand(OMX_CommandFlush, m_input_port);
-}
-
-void COMXCoreComponent::FlushOutput()
-{
- if(!m_handle || m_resource_error)
- return;
-
- OMX_ERRORTYPE omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_output_port, NULL);
-
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::FlushOutput - Error on component %s omx_err(0x%08x)",
- m_componentName.c_str(), (int)omx_err);
- }
- WaitForCommand(OMX_CommandFlush, m_output_port);
-}
-
-// timeout in milliseconds
-OMX_BUFFERHEADERTYPE *COMXCoreComponent::GetInputBuffer(long timeout /*=200*/)
-{
- OMX_BUFFERHEADERTYPE *omx_input_buffer = NULL;
-
- if(!m_handle)
- return NULL;
-
- pthread_mutex_lock(&m_omx_input_mutex);
- struct timespec endtime;
- clock_gettime(CLOCK_REALTIME, &endtime);
- add_timespecs(endtime, timeout);
- while (!m_flush_input)
- {
- if (m_resource_error)
- break;
- if(!m_omx_input_available.empty())
- {
- omx_input_buffer = m_omx_input_available.front();
- m_omx_input_available.pop();
- break;
- }
-
- int retcode = pthread_cond_timedwait(&m_input_buffer_cond, &m_omx_input_mutex, &endtime);
- if (retcode != 0) {
- if (timeout != 0)
- CLog::Log(LOGERROR, "COMXCoreComponent::GetInputBuffer %s wait event timeout",
- m_componentName.c_str());
- break;
- }
- }
- pthread_mutex_unlock(&m_omx_input_mutex);
- return omx_input_buffer;
-}
-
-OMX_BUFFERHEADERTYPE *COMXCoreComponent::GetOutputBuffer(long timeout /*=200*/)
-{
- OMX_BUFFERHEADERTYPE *omx_output_buffer = NULL;
-
- if(!m_handle)
- return NULL;
-
- pthread_mutex_lock(&m_omx_output_mutex);
- struct timespec endtime;
- clock_gettime(CLOCK_REALTIME, &endtime);
- add_timespecs(endtime, timeout);
- while (!m_flush_output)
- {
- if (m_resource_error)
- break;
- if(!m_omx_output_available.empty())
- {
- omx_output_buffer = m_omx_output_available.front();
- m_omx_output_available.pop();
- break;
- }
-
- int retcode = pthread_cond_timedwait(&m_output_buffer_cond, &m_omx_output_mutex, &endtime);
- if (retcode != 0) {
- CLog::Log(LOGERROR, "COMXCoreComponent::GetOutputBuffer %s wait event timeout",
- m_componentName.c_str());
- break;
- }
- }
- pthread_mutex_unlock(&m_omx_output_mutex);
-
- return omx_output_buffer;
-}
-
-
-OMX_ERRORTYPE COMXCoreComponent::WaitForInputDone(long timeout /*=200*/)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- pthread_mutex_lock(&m_omx_input_mutex);
- struct timespec endtime;
- clock_gettime(CLOCK_REALTIME, &endtime);
- add_timespecs(endtime, timeout);
- while (m_input_buffer_count != m_omx_input_available.size())
- {
- if (m_resource_error)
- break;
- int retcode = pthread_cond_timedwait(&m_input_buffer_cond, &m_omx_input_mutex, &endtime);
- if (retcode != 0) {
- if (timeout != 0)
- CLog::Log(LOGERROR, "COMXCoreComponent::WaitForInputDone %s wait event timeout",
- m_componentName.c_str());
- omx_err = OMX_ErrorTimeout;
- break;
- }
- }
- pthread_mutex_unlock(&m_omx_input_mutex);
- return omx_err;
-}
-
-
-OMX_ERRORTYPE COMXCoreComponent::WaitForOutputDone(long timeout /*=200*/)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- pthread_mutex_lock(&m_omx_output_mutex);
- struct timespec endtime;
- clock_gettime(CLOCK_REALTIME, &endtime);
- add_timespecs(endtime, timeout);
- while (m_output_buffer_count != m_omx_output_available.size())
- {
- if (m_resource_error)
- break;
- int retcode = pthread_cond_timedwait(&m_output_buffer_cond, &m_omx_output_mutex, &endtime);
- if (retcode != 0) {
- if (timeout != 0)
- CLog::Log(LOGERROR, "COMXCoreComponent::WaitForOutputDone %s wait event timeout",
- m_componentName.c_str());
- omx_err = OMX_ErrorTimeout;
- break;
- }
- }
- pthread_mutex_unlock(&m_omx_output_mutex);
- return omx_err;
-}
-
-
-OMX_ERRORTYPE COMXCoreComponent::AllocInputBuffers()
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_PARAM_PORTDEFINITIONTYPE portFormat;
- OMX_INIT_STRUCTURE(portFormat);
- portFormat.nPortIndex = m_input_port;
-
- omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
- if(omx_err != OMX_ErrorNone)
- return omx_err;
-
- if(GetState() != OMX_StateIdle)
- {
- if(GetState() != OMX_StateLoaded)
- SetStateForComponent(OMX_StateLoaded);
-
- SetStateForComponent(OMX_StateIdle);
- }
-
- omx_err = EnablePort(m_input_port, false);
- if(omx_err != OMX_ErrorNone)
- return omx_err;
-
- m_input_alignment = portFormat.nBufferAlignment;
- m_input_buffer_count = portFormat.nBufferCountActual;
- m_input_buffer_size = portFormat.nBufferSize;
-
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::AllocInputBuffers component(%s) - port(%d), nBufferCountMin(%u), "
- "nBufferCountActual(%u), nBufferSize(%u), nBufferAlignment(%u)",
- m_componentName.c_str(), GetInputPort(), portFormat.nBufferCountMin,
- portFormat.nBufferCountActual, portFormat.nBufferSize, portFormat.nBufferAlignment);
-
- for (size_t i = 0; i < portFormat.nBufferCountActual; i++)
- {
- OMX_BUFFERHEADERTYPE *buffer = NULL;
-
- omx_err = OMX_AllocateBuffer(m_handle, &buffer, m_input_port, NULL, portFormat.nBufferSize);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::AllocInputBuffers component(%s) - OMX_UseBuffer failed with "
- "omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- return omx_err;
- }
- buffer->nInputPortIndex = m_input_port;
- buffer->nFilledLen = 0;
- buffer->nOffset = 0;
- buffer->pAppPrivate = (void*)i;
- m_omx_input_buffers.push_back(buffer);
- m_omx_input_available.push(buffer);
- }
-
- omx_err = WaitForCommand(OMX_CommandPortEnable, m_input_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::AllocInputBuffers WaitForCommand:OMX_CommandPortEnable failed on "
- "%s omx_err(0x%08x)",
- m_componentName.c_str(), omx_err);
- return omx_err;
- }
-
- m_flush_input = false;
-
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::AllocOutputBuffers()
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_PARAM_PORTDEFINITIONTYPE portFormat;
- OMX_INIT_STRUCTURE(portFormat);
- portFormat.nPortIndex = m_output_port;
-
- omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
- if(omx_err != OMX_ErrorNone)
- return omx_err;
-
- if(GetState() != OMX_StateIdle)
- {
- if(GetState() != OMX_StateLoaded)
- SetStateForComponent(OMX_StateLoaded);
-
- SetStateForComponent(OMX_StateIdle);
- }
-
- omx_err = EnablePort(m_output_port, false);
- if(omx_err != OMX_ErrorNone)
- return omx_err;
-
- m_output_alignment = portFormat.nBufferAlignment;
- m_output_buffer_count = portFormat.nBufferCountActual;
- m_output_buffer_size = portFormat.nBufferSize;
-
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::AllocOutputBuffers component(%s) - port(%d), nBufferCountMin(%u), "
- "nBufferCountActual(%u), nBufferSize(%u) nBufferAlignment(%u)",
- m_componentName.c_str(), m_output_port, portFormat.nBufferCountMin,
- portFormat.nBufferCountActual, portFormat.nBufferSize, portFormat.nBufferAlignment);
-
- for (size_t i = 0; i < portFormat.nBufferCountActual; i++)
- {
- OMX_BUFFERHEADERTYPE *buffer = NULL;
-
- omx_err = OMX_AllocateBuffer(m_handle, &buffer, m_output_port, NULL, portFormat.nBufferSize);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::AllocOutputBuffers component(%s) - OMX_UseBuffer failed with "
- "omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- return omx_err;
- }
- buffer->nOutputPortIndex = m_output_port;
- buffer->nFilledLen = 0;
- buffer->nOffset = 0;
- buffer->pAppPrivate = (void*)i;
- m_omx_output_buffers.push_back(buffer);
- m_omx_output_available.push(buffer);
- }
-
- omx_err = WaitForCommand(OMX_CommandPortEnable, m_output_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::AllocOutputBuffers WaitForCommand:OMX_CommandPortEnable failed "
- "on %s omx_err(0x%08x)",
- m_componentName.c_str(), omx_err);
- return omx_err;
- }
-
- m_flush_output = false;
-
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::FreeInputBuffers()
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- if(m_omx_input_buffers.empty())
- return OMX_ErrorNone;
-
- m_flush_input = true;
-
- omx_err = DisablePort(m_input_port, false);
-
- pthread_mutex_lock(&m_omx_input_mutex);
- pthread_cond_broadcast(&m_input_buffer_cond);
-
- for (size_t i = 0; i < m_omx_input_buffers.size(); i++)
- {
- omx_err = OMX_FreeBuffer(m_handle, m_input_port, m_omx_input_buffers[i]);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::FreeInputBuffers error deallocate omx input buffer on "
- "component %s omx_err(0x%08x)",
- m_componentName.c_str(), omx_err);
- }
- }
- pthread_mutex_unlock(&m_omx_input_mutex);
-
- omx_err = WaitForCommand(OMX_CommandPortDisable, m_input_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::FreeInputBuffers WaitForCommand:OMX_CommandPortDisable failed on "
- "%s omx_err(0x%08x)",
- m_componentName.c_str(), omx_err);
- }
-
- WaitForInputDone(1000);
-
- pthread_mutex_lock(&m_omx_input_mutex);
- assert(m_omx_input_buffers.size() == m_omx_input_available.size());
-
- m_omx_input_buffers.clear();
-
- while (!m_omx_input_available.empty())
- m_omx_input_available.pop();
-
- m_input_alignment = 0;
- m_input_buffer_size = 0;
- m_input_buffer_count = 0;
-
- pthread_mutex_unlock(&m_omx_input_mutex);
-
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::FreeOutputBuffers()
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- if(m_omx_output_buffers.empty())
- return OMX_ErrorNone;
-
- m_flush_output = true;
-
- omx_err = DisablePort(m_output_port, false);
-
- pthread_mutex_lock(&m_omx_output_mutex);
- pthread_cond_broadcast(&m_output_buffer_cond);
-
- for (size_t i = 0; i < m_omx_output_buffers.size(); i++)
- {
- omx_err = OMX_FreeBuffer(m_handle, m_output_port, m_omx_output_buffers[i]);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::FreeOutputBuffers error deallocate omx output buffer on "
- "component %s omx_err(0x%08x)",
- m_componentName.c_str(), omx_err);
- }
- }
- pthread_mutex_unlock(&m_omx_output_mutex);
-
- omx_err = WaitForCommand(OMX_CommandPortDisable, m_output_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::FreeOutputBuffers WaitForCommand:OMX_CommandPortDisable failed "
- "on %s omx_err(0x%08x)",
- m_componentName.c_str(), omx_err);
- }
-
- WaitForOutputDone(1000);
-
- pthread_mutex_lock(&m_omx_output_mutex);
- assert(m_omx_output_buffers.size() == m_omx_output_available.size());
-
- m_omx_output_buffers.clear();
-
- while (!m_omx_output_available.empty())
- m_omx_output_available.pop();
-
- m_output_alignment = 0;
- m_output_buffer_size = 0;
- m_output_buffer_count = 0;
-
- pthread_mutex_unlock(&m_omx_output_mutex);
-
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::DisableAllPorts()
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- OMX_INDEXTYPE idxTypes[] = {
- OMX_IndexParamAudioInit,
- OMX_IndexParamImageInit,
- OMX_IndexParamVideoInit,
- OMX_IndexParamOtherInit
- };
-
- OMX_PORT_PARAM_TYPE ports;
- OMX_INIT_STRUCTURE(ports);
-
- int i;
- for(i=0; i < 4; i++)
- {
- omx_err = OMX_GetParameter(m_handle, idxTypes[i], &ports);
- if(omx_err == OMX_ErrorNone) {
-
- uint32_t j;
- for(j=0; j<ports.nPorts; j++)
- {
- OMX_PARAM_PORTDEFINITIONTYPE portFormat;
- OMX_INIT_STRUCTURE(portFormat);
- portFormat.nPortIndex = ports.nStartPortNumber+j;
-
- omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
- if(omx_err != OMX_ErrorNone)
- {
- if(portFormat.bEnabled == OMX_FALSE)
- continue;
- }
-
- omx_err = OMX_SendCommand(m_handle, OMX_CommandPortDisable, ports.nStartPortNumber+j, NULL);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::DisableAllPorts - Error disable port %d on component %s omx_err(0x%08x)",
- (int)(ports.nStartPortNumber) + j, m_componentName.c_str(), (int)omx_err);
- }
- omx_err = WaitForCommand(OMX_CommandPortDisable, ports.nStartPortNumber+j);
- if(omx_err != OMX_ErrorNone && omx_err != OMX_ErrorSameState)
- return omx_err;
- }
- }
- }
-
- return OMX_ErrorNone;
-}
-
-void COMXCoreComponent::RemoveEvent(OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2)
-{
- for (std::vector<omx_event>::iterator it = m_omx_events.begin(); it != m_omx_events.end(); )
- {
- omx_event event = *it;
-
- if(event.eEvent == eEvent && event.nData1 == nData1 && event.nData2 == nData2)
- {
- it = m_omx_events.erase(it);
- continue;
- }
- ++it;
- }
-}
-
-OMX_ERRORTYPE COMXCoreComponent::AddEvent(OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2)
-{
- omx_event event;
-
- event.eEvent = eEvent;
- event.nData1 = nData1;
- event.nData2 = nData2;
-
- pthread_mutex_lock(&m_omx_event_mutex);
- RemoveEvent(eEvent, nData1, nData2);
- m_omx_events.push_back(event);
- // this allows (all) blocked tasks to be awoken
- pthread_cond_broadcast(&m_omx_event_cond);
- pthread_mutex_unlock(&m_omx_event_mutex);
-
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::AddEvent %s add event event.eEvent 0x%08x event.nData1 0x%08x "
- "event.nData2 %d",
- m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
-#endif
-
- return OMX_ErrorNone;
-}
-
-// timeout in milliseconds
-OMX_ERRORTYPE COMXCoreComponent::WaitForEvent(OMX_EVENTTYPE eventType, long timeout)
-{
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForEvent %s wait event 0x%08x",
- m_componentName.c_str(), (int)eventType);
-#endif
-
- pthread_mutex_lock(&m_omx_event_mutex);
- struct timespec endtime;
- clock_gettime(CLOCK_REALTIME, &endtime);
- add_timespecs(endtime, timeout);
- while(true)
- {
- for (std::vector<omx_event>::iterator it = m_omx_events.begin(); it != m_omx_events.end(); ++it)
- {
- omx_event event = *it;
-
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::WaitForEvent %s inlist event event.eEvent 0x%08x event.nData1 "
- "0x%08x event.nData2 %d",
- m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
-#endif
-
-
- if(event.eEvent == OMX_EventError && event.nData1 == (OMX_U32)OMX_ErrorSameState && event.nData2 == 1)
- {
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::WaitForEvent %s remove event event.eEvent 0x%08x "
- "event.nData1 0x%08x event.nData2 %d",
- m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
-#endif
- m_omx_events.erase(it);
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorNone;
- }
- else if(event.eEvent == OMX_EventError)
- {
- m_omx_events.erase(it);
- pthread_mutex_unlock(&m_omx_event_mutex);
- return (OMX_ERRORTYPE)event.nData1;
- }
- else if(event.eEvent == eventType)
- {
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::WaitForEvent %s remove event event.eEvent 0x%08x "
- "event.nData1 0x%08x event.nData2 %d",
- m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
-#endif
-
- m_omx_events.erase(it);
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorNone;
- }
- }
-
- if (m_resource_error)
- break;
- int retcode = pthread_cond_timedwait(&m_omx_event_cond, &m_omx_event_mutex, &endtime);
- if (retcode != 0)
- {
- if (timeout > 0)
- CLog::Log(LOGERROR, "COMXCoreComponent::WaitForEvent %s wait event 0x%08x timeout %ld",
- m_componentName.c_str(), (int)eventType, timeout);
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorTimeout;
- }
- }
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorNone;
-}
-
-// timeout in milliseconds
-OMX_ERRORTYPE COMXCoreComponent::WaitForCommand(OMX_U32 command, OMX_U32 nData2, long timeout)
-{
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::WaitForCommand %s wait event.eEvent 0x%08x event.command 0x%08x "
- "event.nData2 %d",
- m_componentName.c_str(), (int)OMX_EventCmdComplete, (int)command, (int)nData2);
-#endif
-
- pthread_mutex_lock(&m_omx_event_mutex);
- struct timespec endtime;
- clock_gettime(CLOCK_REALTIME, &endtime);
- add_timespecs(endtime, timeout);
- while(true)
- {
- for (std::vector<omx_event>::iterator it = m_omx_events.begin(); it != m_omx_events.end(); ++it)
- {
- omx_event event = *it;
-
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::WaitForCommand %s inlist event event.eEvent 0x%08x "
- "event.nData1 0x%08x event.nData2 %d",
- m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
-#endif
- if(event.eEvent == OMX_EventError && event.nData1 == (OMX_U32)OMX_ErrorSameState && event.nData2 == 1)
- {
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::WaitForCommand %s remove event event.eEvent 0x%08x "
- "event.nData1 0x%08x event.nData2 %d",
- m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
-#endif
-
- m_omx_events.erase(it);
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorNone;
- }
- else if(event.eEvent == OMX_EventError)
- {
- m_omx_events.erase(it);
- pthread_mutex_unlock(&m_omx_event_mutex);
- return (OMX_ERRORTYPE)event.nData1;
- }
- else if(event.eEvent == OMX_EventCmdComplete && event.nData1 == command && event.nData2 == nData2)
- {
-
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::WaitForCommand %s remove event event.eEvent 0x%08x "
- "event.nData1 0x%08x event.nData2 %d",
- m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
-#endif
-
- m_omx_events.erase(it);
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorNone;
- }
- }
-
- if (m_resource_error)
- break;
- int retcode = pthread_cond_timedwait(&m_omx_event_cond, &m_omx_event_mutex, &endtime);
- if (retcode != 0) {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::WaitForCommand %s wait timeout event.eEvent 0x%08x "
- "event.command 0x%08x event.nData2 %d",
- m_componentName.c_str(), (int)OMX_EventCmdComplete, (int)command, (int)nData2);
-
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorTimeout;
- }
- }
- pthread_mutex_unlock(&m_omx_event_mutex);
- return OMX_ErrorNone;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::SetStateForComponent(OMX_STATETYPE state)
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
- OMX_STATETYPE state_actual = OMX_StateMax;
-
- if(state == state_actual)
- return OMX_ErrorNone;
-
- omx_err = OMX_SendCommand(m_handle, OMX_CommandStateSet, state, 0);
- if (omx_err != OMX_ErrorNone)
- {
- if(omx_err == OMX_ErrorSameState)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::SetStateForComponent - %s same state",
- m_componentName.c_str());
- omx_err = OMX_ErrorNone;
- }
- else
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::SetStateForComponent - %s failed with omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- }
- }
- else
- {
- omx_err = WaitForCommand(OMX_CommandStateSet, state);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::WaitForCommand - %s failed with omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- }
- }
- return omx_err;
-}
-
-OMX_STATETYPE COMXCoreComponent::GetState() const
-{
- if(!m_handle)
- return (OMX_STATETYPE)0;
-
- OMX_STATETYPE state;
-
- OMX_GetState(m_handle, &state);
- return state;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::SetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct)
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err;
-
- omx_err = OMX_SetParameter(m_handle, paramIndex, paramStruct);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::SetParameter - %s failed with omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- }
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::GetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct) const
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err;
-
- omx_err = OMX_GetParameter(m_handle, paramIndex, paramStruct);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::GetParameter - %s failed with omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- }
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::SetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct)
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err;
-
- omx_err = OMX_SetConfig(m_handle, configIndex, configStruct);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::SetConfig - %s failed with omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- }
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) const
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err;
-
- omx_err = OMX_GetConfig(m_handle, configIndex, configStruct);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::GetConfig - %s failed with omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- }
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::SendCommand(OMX_COMMANDTYPE cmd, OMX_U32 cmdParam, OMX_PTR cmdParamData)
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_ERRORTYPE omx_err;
-
- omx_err = OMX_SendCommand(m_handle, cmd, cmdParam, cmdParamData);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::SendCommand - %s failed with omx_err(0x%x)",
- m_componentName.c_str(), omx_err);
- }
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::EnablePort(unsigned int port, bool wait)
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_PARAM_PORTDEFINITIONTYPE portFormat;
- OMX_INIT_STRUCTURE(portFormat);
- portFormat.nPortIndex = port;
-
- OMX_ERRORTYPE omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::EnablePort - Error get port %d status on component %s omx_err(0x%08x)",
- port, m_componentName.c_str(), (int)omx_err);
- }
-
- if(portFormat.bEnabled == OMX_FALSE)
- {
- omx_err = OMX_SendCommand(m_handle, OMX_CommandPortEnable, port, NULL);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::EnablePort - Error enable port %d on component %s omx_err(0x%08x)",
- port, m_componentName.c_str(), (int)omx_err);
- return omx_err;
- }
- else
- {
- if(wait)
- omx_err = WaitForCommand(OMX_CommandPortEnable, port);
- }
- }
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::DisablePort(unsigned int port, bool wait)
-{
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_PARAM_PORTDEFINITIONTYPE portFormat;
- OMX_INIT_STRUCTURE(portFormat);
- portFormat.nPortIndex = port;
-
- OMX_ERRORTYPE omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::DisablePort - Error get port %d status on component %s omx_err(0x%08x)",
- port, m_componentName.c_str(), (int)omx_err);
- }
-
- if(portFormat.bEnabled == OMX_TRUE)
- {
- omx_err = OMX_SendCommand(m_handle, OMX_CommandPortDisable, port, NULL);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::DIsablePort - Error disable port %d on component %s omx_err(0x%08x)",
- port, m_componentName.c_str(), (int)omx_err);
- return omx_err;
- }
- else
- {
- if(wait)
- omx_err = WaitForCommand(OMX_CommandPortDisable, port);
- }
- }
- return omx_err;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::UseEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage)
-{
- OMX_ERRORTYPE omx_err = OMX_ErrorNone;
-
- if(!m_handle)
- return OMX_ErrorUndefined;
-
- OMX_PARAM_PORTDEFINITIONTYPE portFormat;
- OMX_INIT_STRUCTURE(portFormat);
- portFormat.nPortIndex = m_output_port;
-
- omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
- if(omx_err != OMX_ErrorNone)
- return omx_err;
-
- if(GetState() != OMX_StateIdle)
- {
- if(GetState() != OMX_StateLoaded)
- SetStateForComponent(OMX_StateLoaded);
-
- SetStateForComponent(OMX_StateIdle);
- }
-
- omx_err = EnablePort(m_output_port, false);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s - %s EnablePort failed with omx_err(0x%x)", CLASSNAME, __func__,
- m_componentName.c_str(), omx_err);
- return omx_err;
- }
-
- m_output_alignment = portFormat.nBufferAlignment;
- m_output_buffer_count = portFormat.nBufferCountActual;
- m_output_buffer_size = portFormat.nBufferSize;
-
- if (portFormat.nBufferCountActual != 1)
- {
- CLog::Log(LOGERROR, "%s::%s - %s nBufferCountActual unexpected %d", CLASSNAME, __func__,
- m_componentName.c_str(), portFormat.nBufferCountActual);
- return omx_err;
- }
-
- CLog::Log(LOGDEBUG,
- "%s::%s component(%s) - port(%d), nBufferCountMin(%u), nBufferCountActual(%u), "
- "nBufferSize(%u) nBufferAlignment(%u)",
- CLASSNAME, __func__, m_componentName.c_str(), m_output_port, portFormat.nBufferCountMin,
- portFormat.nBufferCountActual, portFormat.nBufferSize, portFormat.nBufferAlignment);
-
- for (size_t i = 0; i < portFormat.nBufferCountActual; i++)
- {
- omx_err = OMX_UseEGLImage(m_handle, ppBufferHdr, nPortIndex, pAppPrivate, eglImage);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "%s::%s - %s failed with omx_err(0x%x)", CLASSNAME, __func__,
- m_componentName.c_str(), omx_err);
- return omx_err;
- }
-
- OMX_BUFFERHEADERTYPE *buffer = *ppBufferHdr;
- buffer->nOutputPortIndex = m_output_port;
- buffer->nFilledLen = 0;
- buffer->nOffset = 0;
- buffer->pAppPrivate = (void*)i;
- m_omx_output_buffers.push_back(buffer);
- m_omx_output_available.push(buffer);
- }
-
- omx_err = WaitForCommand(OMX_CommandPortEnable, m_output_port);
- if(omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, " %s::%s - %s EnablePort failed with omx_err(0x%x)", CLASSNAME, __func__,
- m_componentName.c_str(), omx_err);
- return omx_err;
- }
- m_flush_output = false;
-
- return omx_err;
-}
-
-bool COMXCoreComponent::Initialize( const std::string &component_name, OMX_INDEXTYPE index)
-{
- OMX_ERRORTYPE omx_err;
-
- m_input_port = 0;
- m_output_port = 0;
- m_handle = NULL;
-
- m_input_alignment = 0;
- m_input_buffer_size = 0;
- m_input_buffer_count = 0;
-
- m_output_alignment = 0;
- m_output_buffer_size = 0;
- m_output_buffer_count = 0;
- m_flush_input = false;
- m_flush_output = false;
- m_resource_error = false;
-
- m_eos = false;
-
- m_exit = false;
-
- m_omx_events.clear();
- m_ignore_error = OMX_ErrorNone;
-
- m_componentName = component_name;
-
- m_callbacks.EventHandler = &COMXCoreComponent::DecoderEventHandlerCallback;
- m_callbacks.EmptyBufferDone = &COMXCoreComponent::DecoderEmptyBufferDoneCallback;
- m_callbacks.FillBufferDone = &COMXCoreComponent::DecoderFillBufferDoneCallback;
-
- // Get video component handle setting up callbacks, component is in loaded state on return.
- if(!m_handle)
- {
- omx_err = m_DllOMX->OMX_GetHandle(&m_handle, (char*)component_name.c_str(), this, &m_callbacks);
- if (!m_handle || omx_err != OMX_ErrorNone)
- {
- CLog::Log(
- LOGERROR,
- "COMXCoreComponent::Initialize - could not get component handle for %s omx_err(0x%08x)",
- component_name.c_str(), (int)omx_err);
- Deinitialize();
- return false;
- }
- }
-
- OMX_PORT_PARAM_TYPE port_param;
- OMX_INIT_STRUCTURE(port_param);
-
- omx_err = OMX_GetParameter(m_handle, index, &port_param);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(
- LOGERROR,
- "COMXCoreComponent::Initialize - could not get port_param for component %s omx_err(0x%08x)",
- component_name.c_str(), (int)omx_err);
- }
-
- omx_err = DisableAllPorts();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR,
- "COMXCoreComponent::Initialize - error disable ports on component %s omx_err(0x%08x)",
- component_name.c_str(), (int)omx_err);
- }
-
- m_input_port = port_param.nStartPortNumber;
- m_output_port = m_input_port + 1;
-
- if(m_componentName == "OMX.broadcom.audio_mixer")
- {
- m_input_port = port_param.nStartPortNumber + 1;
- m_output_port = port_param.nStartPortNumber;
- }
-
- if (m_output_port > port_param.nStartPortNumber+port_param.nPorts-1)
- m_output_port = port_param.nStartPortNumber+port_param.nPorts-1;
-
- CLog::Log(LOGDEBUG, "COMXCoreComponent::Initialize %s input port %d output port %d m_handle %p",
- m_componentName.c_str(), m_input_port, m_output_port, m_handle);
-
- m_exit = false;
- m_flush_input = false;
- m_flush_output = false;
-
- return true;
-}
-
-void COMXCoreComponent::ResetEos()
-{
- pthread_mutex_lock(&m_omx_eos_mutex);
- m_eos = false;
- pthread_mutex_unlock(&m_omx_eos_mutex);
-}
-
-bool COMXCoreComponent::Deinitialize()
-{
- OMX_ERRORTYPE omx_err;
-
- m_exit = true;
-
- m_flush_input = true;
- m_flush_output = true;
-
- if(m_handle)
- {
- FlushAll();
-
- FreeOutputBuffers();
- FreeInputBuffers();
-
- TransitionToStateLoaded();
-
- CLog::Log(LOGDEBUG, "COMXCoreComponent::Deinitialize : %s handle %p", m_componentName.c_str(),
- m_handle);
- omx_err = m_DllOMX->OMX_FreeHandle(m_handle);
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCoreComponent::Deinitialize - failed to free handle for component %s omx_err(0x%08x)",
- m_componentName.c_str(), omx_err);
- }
- m_handle = NULL;
-
- m_input_port = 0;
- m_output_port = 0;
- m_componentName = "";
- m_resource_error = false;
- }
-
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-// DecoderEventHandler -- OMX event callback
-OMX_ERRORTYPE COMXCoreComponent::DecoderEventHandlerCallback(
- OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_EVENTTYPE eEvent,
- OMX_U32 nData1,
- OMX_U32 nData2,
- OMX_PTR pEventData)
-{
- if(!pAppData)
- return OMX_ErrorNone;
-
- COMXCoreComponent *ctx = static_cast<COMXCoreComponent*>(pAppData);
- return ctx->DecoderEventHandler(hComponent, eEvent, nData1, nData2, pEventData);
-}
-
-// DecoderEmptyBufferDone -- OMXCore input buffer has been emptied
-OMX_ERRORTYPE COMXCoreComponent::DecoderEmptyBufferDoneCallback(
- OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_BUFFERHEADERTYPE* pBuffer)
-{
- if(!pAppData)
- return OMX_ErrorNone;
-
- COMXCoreComponent *ctx = static_cast<COMXCoreComponent*>(pAppData);
- return ctx->DecoderEmptyBufferDone( hComponent, pBuffer);
-}
-
-// DecoderFillBufferDone -- OMXCore output buffer has been filled
-OMX_ERRORTYPE COMXCoreComponent::DecoderFillBufferDoneCallback(
- OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_BUFFERHEADERTYPE* pBuffer)
-{
- if(!pAppData)
- return OMX_ErrorNone;
-
- COMXCoreComponent *ctx = static_cast<COMXCoreComponent*>(pAppData);
- return ctx->DecoderFillBufferDone(hComponent, pBuffer);
-}
-
-OMX_ERRORTYPE COMXCoreComponent::DecoderEmptyBufferDone(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE* pBuffer)
-{
- if(m_exit)
- return OMX_ErrorNone;
-
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "COMXCoreComponent::DecoderEmptyBufferDone component(%s) %p %d/%d",
- m_componentName.c_str(), pBuffer, m_omx_input_available.size(), m_input_buffer_count);
-#endif
- pthread_mutex_lock(&m_omx_input_mutex);
- m_omx_input_available.push(pBuffer);
-
- // this allows (all) blocked tasks to be awoken
- pthread_cond_broadcast(&m_input_buffer_cond);
-
- pthread_mutex_unlock(&m_omx_input_mutex);
-
- return OMX_ErrorNone;
-}
-
-OMX_ERRORTYPE COMXCoreComponent::DecoderFillBufferDone(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE* pBuffer)
-{
- if(m_exit)
- return OMX_ErrorNone;
-
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "COMXCoreComponent::DecoderFillBufferDone component(%s) %p %d/%d",
- m_componentName.c_str(), pBuffer, m_omx_output_available.size(), m_output_buffer_count);
-#endif
- pthread_mutex_lock(&m_omx_output_mutex);
- m_omx_output_available.push(pBuffer);
-
- // this allows (all) blocked tasks to be awoken
- pthread_cond_broadcast(&m_output_buffer_cond);
-
- pthread_mutex_unlock(&m_omx_output_mutex);
-
- return OMX_ErrorNone;
-}
-
-// DecoderEmptyBufferDone -- OMXCore input buffer has been emptied
-////////////////////////////////////////////////////////////////////////////////////////////
-// Component event handler -- OMX event callback
-OMX_ERRORTYPE COMXCoreComponent::DecoderEventHandler(
- OMX_HANDLETYPE hComponent,
- OMX_EVENTTYPE eEvent,
- OMX_U32 nData1,
- OMX_U32 nData2,
- OMX_PTR pEventData)
-{
-#ifdef OMX_DEBUG_EVENTS
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::%s - %s eEvent(0x%x), nData1(0x%x), nData2(0x%x), pEventData(0x%p)\n",
- __func__, GetName().c_str(), eEvent, nData1, nData2, pEventData);
-#endif
-
- // if the error is expected, then we can skip it
- if (eEvent == OMX_EventError && (OMX_S32)nData1 == m_ignore_error)
- {
- CLog::Log(LOGDEBUG,
- "COMXCoreComponent::%s - %s Ignoring expected event: eEvent(0x%x), nData1(0x%x), nData2(0x%x), pEventData(0x%p)\n",
- __func__, GetName().c_str(), eEvent, nData1, nData2, pEventData);
- m_ignore_error = OMX_ErrorNone;
- return OMX_ErrorNone;
- }
- AddEvent(eEvent, nData1, nData2);
-
- switch (eEvent)
- {
- case OMX_EventCmdComplete:
-
- switch(nData1)
- {
- case OMX_CommandStateSet:
- switch ((int)nData2)
- {
- case OMX_StateInvalid:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateInvalid", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- case OMX_StateLoaded:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateLoaded", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- case OMX_StateIdle:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateIdle", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- case OMX_StateExecuting:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateExecuting", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- case OMX_StatePause:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StatePause", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- case OMX_StateWaitForResources:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateWaitForResources", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- default:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG,
- "%s::%s %s - Unknown OMX_Statexxxxx, state(%d)\n", CLASSNAME, __func__, GetName().c_str(), (int)nData2);
- #endif
- break;
- }
- break;
- case OMX_CommandFlush:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandFlush, port %d", CLASSNAME, __func__,
- GetName().c_str(), (int)nData2);
-#endif
- break;
- case OMX_CommandPortDisable:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandPortDisable, nData1(0x%x), port %d",
- CLASSNAME, __func__, GetName().c_str(), nData1, (int)nData2);
-#endif
- break;
- case OMX_CommandPortEnable:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandPortEnable, nData1(0x%x), port %d", CLASSNAME,
- __func__, GetName().c_str(), nData1, (int)nData2);
-#endif
- break;
- #if defined(OMX_DEBUG_EVENTHANDLER)
- case OMX_CommandMarkBuffer:
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandMarkBuffer, nData1(0x%x), port %d", CLASSNAME,
- __func__, GetName().c_str(), nData1, (int)nData2);
- break;
- #endif
- }
- break;
- case OMX_EventBufferFlag:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventBufferFlag(input)", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- if(nData2 & OMX_BUFFERFLAG_EOS)
- {
- pthread_mutex_lock(&m_omx_eos_mutex);
- m_eos = true;
- pthread_mutex_unlock(&m_omx_eos_mutex);
- }
- break;
- case OMX_EventPortSettingsChanged:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventPortSettingsChanged(output)", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- case OMX_EventParamOrConfigChanged:
- #if defined(OMX_DEBUG_EVENTHANDLER)
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventParamOrConfigChanged(output)", CLASSNAME, __func__,
- GetName().c_str());
-#endif
- break;
- #if defined(OMX_DEBUG_EVENTHANDLER)
- case OMX_EventMark:
- CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventMark", CLASSNAME, __func__, GetName().c_str());
- break;
- case OMX_EventResourcesAcquired:
- CLog::Log(LOGDEBUG, "%s::%s %s- OMX_EventResourcesAcquired", CLASSNAME, __func__,
- GetName().c_str());
- break;
- #endif
- case OMX_EventError:
- switch((OMX_S32)nData1)
- {
- case OMX_ErrorSameState:
- //#if defined(OMX_DEBUG_EVENTHANDLER)
- //CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorSameState, same state", CLASSNAME, __func__, GetName().c_str());
- //#endif
- break;
- case OMX_ErrorInsufficientResources:
- CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorInsufficientResources, insufficient resources",
- CLASSNAME, __func__, GetName().c_str());
- m_resource_error = true;
- break;
- case OMX_ErrorFormatNotDetected:
- CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorFormatNotDetected, cannot parse input stream",
- CLASSNAME, __func__, GetName().c_str());
- break;
- case OMX_ErrorPortUnpopulated:
- CLog::Log(LOGWARNING, "%s::%s %s - OMX_ErrorPortUnpopulated port %d", CLASSNAME, __func__,
- GetName().c_str(), (int)nData2);
- break;
- case OMX_ErrorStreamCorrupt:
- CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorStreamCorrupt, Bitstream corrupt", CLASSNAME,
- __func__, GetName().c_str());
- m_resource_error = true;
- break;
- case OMX_ErrorUnsupportedSetting:
- CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorUnsupportedSetting, unsupported setting",
- CLASSNAME, __func__, GetName().c_str());
- break;
- default:
- CLog::Log(LOGERROR, "%s::%s %s - OMX_EventError detected, nData1(0x%x), port %d",
- CLASSNAME, __func__, GetName().c_str(), nData1, (int)nData2);
- break;
- }
- // wake things up
- if (m_resource_error)
- {
- pthread_cond_broadcast(&m_output_buffer_cond);
- pthread_cond_broadcast(&m_input_buffer_cond);
- pthread_cond_broadcast(&m_omx_event_cond);
- }
- break;
- default:
- CLog::Log(LOGWARNING, "%s::%s %s - Unknown eEvent(0x%x), nData1(0x%x), port %d", CLASSNAME,
- __func__, GetName().c_str(), eEvent, nData1, (int)nData2);
- break;
- }
-
- return OMX_ErrorNone;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////
-COMXCore::COMXCore()
-{
- m_is_open = false;
-
- m_DllOMX = new DllOMX();
-}
-
-COMXCore::~COMXCore()
-{
- delete m_DllOMX;
-}
-
-bool COMXCore::Initialize()
-{
- if(!m_DllOMX->Load())
- return false;
-
- OMX_ERRORTYPE omx_err = m_DllOMX->OMX_Init();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCore::Initialize - OMXCore failed to init, omx_err(0x%08x)", omx_err);
- return false;
- }
-
- m_is_open = true;
- return true;
-}
-
-void COMXCore::Deinitialize()
-{
- if(m_is_open)
- {
- OMX_ERRORTYPE omx_err = m_DllOMX->OMX_Deinit();
- if (omx_err != OMX_ErrorNone)
- {
- CLog::Log(LOGERROR, "COMXCore::Deinitialize - OMXCore failed to deinit, omx_err(0x%08x)", omx_err);
- }
- m_DllOMX->Unload();
- }
-}
diff --git a/xbmc/platform/linux/OMXCore.h b/xbmc/platform/linux/OMXCore.h
deleted file mode 100644
index 84d043469b..0000000000
--- a/xbmc/platform/linux/OMXCore.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2010-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 <string>
-#include <queue>
-#include <vector>
-
-//! @todo should this be in configure
-#ifndef OMX_SKIP64BIT
-#define OMX_SKIP64BIT
-#endif
-
-#include "DllOMX.h"
-
-#include <semaphore.h>
-
-////////////////////////////////////////////////////////////////////////////////////////////
-// debug spew defines
-#if 0
-#define OMX_DEBUG_VERBOSE
-#define OMX_DEBUG_EVENTHANDLER
-#endif
-
-#define OMX_INIT_STRUCTURE(a) \
- memset(&(a), 0, sizeof(a)); \
- (a).nSize = sizeof(a); \
- (a).nVersion.s.nVersionMajor = OMX_VERSION_MAJOR; \
- (a).nVersion.s.nVersionMinor = OMX_VERSION_MINOR; \
- (a).nVersion.s.nRevision = OMX_VERSION_REVISION; \
- (a).nVersion.s.nStep = OMX_VERSION_STEP
-
-#define OMX_MAX_PORTS 10
-
-typedef struct omx_event {
- OMX_EVENTTYPE eEvent;
- OMX_U32 nData1;
- OMX_U32 nData2;
-} omx_event;
-
-class COMXCore;
-class COMXCoreComponent;
-class COMXCoreTunnel;
-class COMXCoreClock;
-
-class COMXCoreTunnel
-{
-public:
- COMXCoreTunnel();
- ~COMXCoreTunnel();
-
- void Initialize(COMXCoreComponent *src_component, unsigned int src_port, COMXCoreComponent *dst_component, unsigned int dst_port);
- bool IsInitialized() const { return m_tunnel_set; }
- OMX_ERRORTYPE Deestablish(bool noWait = false);
- OMX_ERRORTYPE Establish(bool enable_ports = true, bool disable_ports = false);
-private:
- COMXCoreComponent *m_src_component;
- COMXCoreComponent *m_dst_component;
- unsigned int m_src_port;
- unsigned int m_dst_port;
- DllOMX *m_DllOMX;
- bool m_tunnel_set;
-};
-
-class COMXCoreComponent
-{
-public:
- COMXCoreComponent();
- ~COMXCoreComponent();
-
- OMX_HANDLETYPE GetComponent() const { return m_handle; }
- unsigned int GetInputPort() const { return m_input_port; }
- unsigned int GetOutputPort() const { return m_output_port; }
- std::string GetName() const { return m_componentName; }
-
- OMX_ERRORTYPE DisableAllPorts();
- void RemoveEvent(OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2);
- OMX_ERRORTYPE AddEvent(OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2);
- OMX_ERRORTYPE WaitForEvent(OMX_EVENTTYPE event, long timeout = 300);
- OMX_ERRORTYPE WaitForCommand(OMX_U32 command, OMX_U32 nData2, long timeout = 2000);
- OMX_ERRORTYPE SetStateForComponent(OMX_STATETYPE state);
- OMX_STATETYPE GetState() const;
- OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct);
- OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct) const;
- OMX_ERRORTYPE SetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct);
- OMX_ERRORTYPE GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) const;
- OMX_ERRORTYPE SendCommand(OMX_COMMANDTYPE cmd, OMX_U32 cmdParam, OMX_PTR cmdParamData);
- OMX_ERRORTYPE EnablePort(unsigned int port, bool wait = true);
- OMX_ERRORTYPE DisablePort(unsigned int port, bool wait = true);
- OMX_ERRORTYPE UseEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage);
-
- bool Initialize( const std::string &component_name, OMX_INDEXTYPE index);
- bool IsInitialized() const { return m_handle != NULL; }
- bool Deinitialize();
-
- // OMXCore Decoder delegate callback routines.
- static OMX_ERRORTYPE DecoderEventHandlerCallback(OMX_HANDLETYPE hComponent, OMX_PTR pAppData,
- OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, OMX_PTR pEventData);
- static OMX_ERRORTYPE DecoderEmptyBufferDoneCallback(
- OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_BUFFERHEADERTYPE* pBuffer);
- static OMX_ERRORTYPE DecoderFillBufferDoneCallback(
- OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_BUFFERHEADERTYPE* pBufferHeader);
-
- // OMXCore decoder callback routines.
- OMX_ERRORTYPE DecoderEventHandler(OMX_HANDLETYPE hComponent,
- OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, OMX_PTR pEventData);
- OMX_ERRORTYPE DecoderEmptyBufferDone(
- OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE* pBuffer);
- OMX_ERRORTYPE DecoderFillBufferDone(
- OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE* pBuffer);
-
- void TransitionToStateLoaded();
-
- OMX_ERRORTYPE EmptyThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer);
- OMX_ERRORTYPE FillThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer);
- OMX_ERRORTYPE FreeOutputBuffer(OMX_BUFFERHEADERTYPE *omx_buffer);
-
- unsigned int GetInputBufferSize() const { return m_input_buffer_count * m_input_buffer_size; }
- unsigned int GetOutputBufferSize() const { return m_output_buffer_count * m_output_buffer_size; }
-
- unsigned int GetInputBufferSpace() const { return m_omx_input_available.size() * m_input_buffer_size; }
- unsigned int GetOutputBufferSpace() const { return m_omx_output_available.size() * m_output_buffer_size; }
-
- void FlushAll();
- void FlushInput();
- void FlushOutput();
-
- OMX_BUFFERHEADERTYPE *GetInputBuffer(long timeout=200);
- OMX_BUFFERHEADERTYPE *GetOutputBuffer(long timeout=200);
-
- OMX_ERRORTYPE AllocInputBuffers();
- OMX_ERRORTYPE AllocOutputBuffers();
-
- OMX_ERRORTYPE FreeInputBuffers();
- OMX_ERRORTYPE FreeOutputBuffers();
-
- OMX_ERRORTYPE WaitForInputDone(long timeout=200);
- OMX_ERRORTYPE WaitForOutputDone(long timeout=200);
-
- bool IsEOS() const { return m_eos; }
- bool BadState() const { return m_resource_error; }
- void ResetEos();
- void IgnoreNextError(OMX_S32 error) { m_ignore_error = error; }
-
-private:
- OMX_HANDLETYPE m_handle;
- unsigned int m_input_port;
- unsigned int m_output_port;
- std::string m_componentName;
- pthread_mutex_t m_omx_event_mutex;
- pthread_mutex_t m_omx_eos_mutex;
- std::vector<omx_event> m_omx_events;
- OMX_S32 m_ignore_error;
-
- OMX_CALLBACKTYPE m_callbacks;
-
- // OMXCore input buffers (demuxer packets)
- pthread_mutex_t m_omx_input_mutex;
- std::queue<OMX_BUFFERHEADERTYPE*> m_omx_input_available;
- std::vector<OMX_BUFFERHEADERTYPE*> m_omx_input_buffers;
- unsigned int m_input_alignment;
- unsigned int m_input_buffer_size;
- unsigned int m_input_buffer_count;
-
- // OMXCore output buffers (video frames)
- pthread_mutex_t m_omx_output_mutex;
- std::queue<OMX_BUFFERHEADERTYPE*> m_omx_output_available;
- std::vector<OMX_BUFFERHEADERTYPE*> m_omx_output_buffers;
- unsigned int m_output_alignment;
- unsigned int m_output_buffer_size;
- unsigned int m_output_buffer_count;
-
- bool m_exit;
- DllOMX *m_DllOMX;
- pthread_cond_t m_input_buffer_cond;
- pthread_cond_t m_output_buffer_cond;
- pthread_cond_t m_omx_event_cond;
- bool m_eos;
- bool m_flush_input;
- bool m_flush_output;
- bool m_resource_error;
-};
-
-class COMXCore
-{
-public:
- COMXCore();
- ~COMXCore();
-
- // initialize OMXCore and get decoder component
- bool Initialize();
- void Deinitialize();
- DllOMX *GetDll() { return m_DllOMX; }
-
-protected:
- bool m_is_open;
- DllOMX *m_DllOMX;
-};
diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp
deleted file mode 100644
index f750fa0656..0000000000
--- a/xbmc/platform/linux/RBP.cpp
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2005-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "RBP.h"
-
-#include "ServiceBroker.h"
-#include "cores/omxplayer/OMXImage.h"
-#include "rpi/rpi_user_vcsm.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "utils/TimeUtils.h"
-#include "utils/log.h"
-
-#include <assert.h>
-
-#include <interface/mmal/mmal.h>
-#include <sys/ioctl.h>
-
-#define MAJOR_NUM 100
-#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)
-#define DEVICE_FILE_NAME "/dev/vcio"
-
-static int mbox_open();
-static void mbox_close(int file_desc);
-
-typedef struct vc_image_extra_uv_s {
- void *u, *v;
- int vpitch;
-} VC_IMAGE_EXTRA_UV_T;
-
-typedef union {
- VC_IMAGE_EXTRA_UV_T uv;
-} VC_IMAGE_EXTRA_T;
-
-struct VC_IMAGE_T {
- unsigned short type; /* should restrict to 16 bits */
- unsigned short info; /* format-specific info; zero for VC02 behaviour */
- unsigned short width; /* width in pixels */
- unsigned short height; /* height in pixels */
- int pitch; /* pitch of image_data array in bytes */
- int size; /* number of bytes available in image_data array */
- void *image_data; /* pixel data */
- VC_IMAGE_EXTRA_T extra; /* extra data like palette pointer */
- void *metadata; /* metadata header for the image */
- void *pool_object; /* nonNULL if image was allocated from a vc_pool */
- uint32_t mem_handle; /* the mem handle for relocatable memory storage */
- int metadata_size; /* size of metadata of each channel in bytes */
- int channel_offset; /* offset of consecutive channels in bytes */
- uint32_t video_timestamp;/* 90000 Hz RTP times domain - derived from audio timestamp */
- uint8_t num_channels; /* number of channels (2 for stereo) */
- uint8_t current_channel;/* the channel this header is currently pointing to */
- uint8_t linked_multichann_flag;/* Indicate the header has the linked-multichannel structure*/
- uint8_t is_channel_linked; /* Track if the above structure is been used to link the header
- into a linked-mulitchannel image */
- uint8_t channel_index; /* index of the channel this header represents while
- it is being linked. */
- uint8_t _dummy[3]; /* pad struct to 64 bytes */
-};
-typedef int vc_image_t_size_check[(sizeof(VC_IMAGE_T) == 64) * 2 - 1];
-
-CRBP::CRBP()
-{
- m_initialized = false;
- m_omx_initialized = false;
- m_DllBcmHost = new DllBcmHost();
- m_OMX = new COMXCore();
- m_display = DISPMANX_NO_HANDLE;
- m_mb = mbox_open();
- vcsm_init();
- m_vsync_count = 0;
- m_vsync_time = 0;
-}
-
-CRBP::~CRBP()
-{
- Deinitialize();
- delete m_OMX;
- delete m_DllBcmHost;
-}
-
-bool CRBP::Initialize()
-{
- CSingleLock lock(m_critSection);
- if (m_initialized)
- return true;
-
- m_initialized = m_DllBcmHost->Load();
- if(!m_initialized)
- return false;
-
- m_DllBcmHost->bcm_host_init();
-
- m_omx_initialized = m_OMX->Initialize();
- if(!m_omx_initialized)
- return false;
-
- char response[80] = "";
- m_arm_mem = 0;
- m_gpu_mem = 0;
- m_codec_mpg2_enabled = false;
- m_codec_wvc1_enabled = false;
-
- if (vc_gencmd(response, sizeof response, "get_mem arm") == 0)
- vc_gencmd_number_property(response, "arm", &m_arm_mem);
- if (vc_gencmd(response, sizeof response, "get_mem gpu") == 0)
- vc_gencmd_number_property(response, "gpu", &m_gpu_mem);
-
- if (vc_gencmd(response, sizeof response, "codec_enabled MPG2") == 0)
- m_codec_mpg2_enabled = strcmp("MPG2=enabled", response) == 0;
- if (vc_gencmd(response, sizeof response, "codec_enabled WVC1") == 0)
- m_codec_wvc1_enabled = strcmp("WVC1=enabled", response) == 0;
-
- if (m_gpu_mem < 128)
- setenv("V3D_DOUBLE_BUFFER", "1", 1);
-
- m_gui_resolution_limit = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt("videoscreen.limitgui");
- if (!m_gui_resolution_limit)
- m_gui_resolution_limit = m_gpu_mem < 128 ? 720:1080;
-
- g_OMXImage.Initialize();
- m_omx_image_init = true;
- return true;
-}
-
-void CRBP::LogFirmwareVersion()
-{
- char response[1024];
- m_DllBcmHost->vc_gencmd(response, sizeof response, "version");
- response[sizeof(response) - 1] = '\0';
- CLog::Log(LOGINFO, "Raspberry PI firmware version: %s", response);
- CLog::Log(LOGINFO, "ARM mem: %dMB GPU mem: %dMB MPG2:%d WVC1:%d", m_arm_mem, m_gpu_mem,
- m_codec_mpg2_enabled, m_codec_wvc1_enabled);
- m_DllBcmHost->vc_gencmd(response, sizeof response, "get_config int");
- response[sizeof(response) - 1] = '\0';
- CLog::Log(LOGINFO, "Config:\n%s", response);
- m_DllBcmHost->vc_gencmd(response, sizeof response, "get_config str");
- response[sizeof(response) - 1] = '\0';
- CLog::Log(LOGINFO, "Config:\n%s", response);
-}
-
-static void vsync_callback_static(DISPMANX_UPDATE_HANDLE_T u, void *arg)
-{
- CRBP *rbp = reinterpret_cast<CRBP*>(arg);
- rbp->VSyncCallback();
-}
-
-DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device)
-{
- CSingleLock lock(m_critSection);
- if (m_display == DISPMANX_NO_HANDLE)
- {
- m_display = vc_dispmanx_display_open( 0 /*screen*/ );
- int s = vc_dispmanx_vsync_callback(m_display, vsync_callback_static, (void *)this);
- assert(s == 0);
- }
- return m_display;
-}
-
-void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display)
-{
- CSingleLock lock(m_critSection);
- assert(display == m_display);
- int s = vc_dispmanx_vsync_callback(m_display, NULL, NULL);
- assert(s == 0);
- vc_dispmanx_display_close(m_display);
- m_display = DISPMANX_NO_HANDLE;
-}
-
-void CRBP::GetDisplaySize(int &width, int &height)
-{
- CSingleLock lock(m_critSection);
- DISPMANX_MODEINFO_T info;
- if (m_display != DISPMANX_NO_HANDLE && vc_dispmanx_display_get_info(m_display, &info) == 0)
- {
- width = info.width;
- height = info.height;
- }
- else
- {
- width = 0;
- height = 0;
- }
-}
-
-unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only)
-{
- DISPMANX_RESOURCE_HANDLE_T resource;
- VC_RECT_T rect;
- unsigned char *image = NULL;
- uint32_t vc_image_ptr;
- int stride;
- uint32_t flags = 0;
-
- if (video_only)
- flags |= DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL;
- if (swap_red_blue)
- flags |= DISPMANX_SNAPSHOT_SWAP_RED_BLUE;
- if (!pstride)
- flags |= DISPMANX_SNAPSHOT_PACK;
-
- stride = ((width + 15) & ~15) * 4;
-
- CSingleLock lock(m_critSection);
- if (m_display != DISPMANX_NO_HANDLE)
- {
- image = new unsigned char [height * stride];
- resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr );
-
- vc_dispmanx_snapshot(m_display, resource, (DISPMANX_TRANSFORM_T)flags);
-
- vc_dispmanx_rect_set(&rect, 0, 0, width, height);
- vc_dispmanx_resource_read_data(resource, &rect, image, stride);
- vc_dispmanx_resource_delete( resource );
- }
- if (pstride)
- *pstride = stride;
- return image;
-}
-
-void CRBP::VSyncCallback()
-{
- CSingleLock lock(m_vsync_lock);
- m_vsync_count++;
- m_vsync_time = CurrentHostCounter();
- m_vsync_cond.notifyAll();
-}
-
-uint32_t CRBP::WaitVsync(uint32_t target)
-{
- CSingleLock vlock(m_vsync_lock);
- DISPMANX_DISPLAY_HANDLE_T display = m_display;
- XbmcThreads::EndTime delay(50);
- if (target == ~0U)
- target = m_vsync_count+1;
- while (!delay.IsTimePast())
- {
- if ((signed)(m_vsync_count - target) >= 0)
- break;
- if (!m_vsync_cond.wait(vlock, delay.MillisLeft()))
- break;
- }
- if ((signed)(m_vsync_count - target) < 0)
- CLog::Log(LOGDEBUG, "CRBP::%s no vsync %d/%d display:%x(%x) delay:%d", __FUNCTION__, m_vsync_count, target, m_display, display, delay.MillisLeft());
-
- return m_vsync_count;
-}
-
-uint32_t CRBP::LastVsync(int64_t &time)
-{
- CSingleLock lock(m_vsync_lock);
- time = m_vsync_time;
- return m_vsync_count;
-}
-
-uint32_t CRBP::LastVsync()
-{
- int64_t time = 0;
- return LastVsync(time);
-}
-
-void CRBP::Deinitialize()
-{
- if (m_omx_image_init)
- g_OMXImage.Deinitialize();
-
- if(m_omx_initialized)
- m_OMX->Deinitialize();
-
- m_DllBcmHost->bcm_host_deinit();
-
- if(m_initialized)
- m_DllBcmHost->Unload();
-
- m_omx_image_init = false;
- m_initialized = false;
- m_omx_initialized = false;
- if (m_mb)
- mbox_close(m_mb);
- m_mb = 0;
- vcsm_exit();
-}
-
-static int mbox_property(int file_desc, void *buf)
-{
- int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf);
-
- if (ret_val < 0)
- {
- CLog::Log(LOGERROR, "%s: ioctl_set_msg failed:%d", __FUNCTION__, ret_val);
- }
- return ret_val;
-}
-
-static int mbox_open()
-{
- int file_desc;
-
- // open a char device file used for communicating with kernel mbox driver
- file_desc = open(DEVICE_FILE_NAME, 0);
- if (file_desc < 0)
- CLog::Log(LOGERROR, "%s: Can't open device file: %s (%d)", __FUNCTION__, DEVICE_FILE_NAME, file_desc);
-
- return file_desc;
-}
-
-static void mbox_close(int file_desc)
-{
- close(file_desc);
-}
-
-static unsigned mem_lock(int file_desc, unsigned handle)
-{
- int i=0;
- unsigned p[32];
- p[i++] = 0; // size
- p[i++] = 0x00000000; // process request
-
- p[i++] = 0x3000d; // (the tag id)
- p[i++] = 4; // (size of the buffer)
- p[i++] = 4; // (size of the data)
- p[i++] = handle;
-
- p[i++] = 0x00000000; // end tag
- p[0] = i*sizeof *p; // actual size
-
- mbox_property(file_desc, p);
- return p[5];
-}
-
-static unsigned mem_unlock(int file_desc, unsigned handle)
-{
- int i=0;
- unsigned p[32];
- p[i++] = 0; // size
- p[i++] = 0x00000000; // process request
-
- p[i++] = 0x3000e; // (the tag id)
- p[i++] = 4; // (size of the buffer)
- p[i++] = 4; // (size of the data)
- p[i++] = handle;
-
- p[i++] = 0x00000000; // end tag
- p[0] = i*sizeof *p; // actual size
-
- mbox_property(file_desc, p);
- return p[5];
-}
-
-
-#define GET_VCIMAGE_PARAMS 0x30044
-static int get_image_params(int file_desc, VC_IMAGE_T * img)
-{
- uint32_t buf[sizeof(*img) / sizeof(uint32_t) + 32];
- uint32_t * p = buf;
- void * rimg;
- int rv;
-
- *p++ = 0; // size
- *p++ = 0; // process request
- *p++ = GET_VCIMAGE_PARAMS;
- *p++ = sizeof(*img);
- *p++ = sizeof(*img);
- rimg = p;
- memcpy(p, img, sizeof(*img));
- p += sizeof(*img) / sizeof(*p);
- *p++ = 0; // End tag
- buf[0] = (p - buf) * sizeof(*p);
-
- rv = mbox_property(file_desc, buf);
- memcpy(img, rimg, sizeof(*img));
-
- return rv;
-}
-
-CGPUMEM::CGPUMEM(unsigned int numbytes, bool cached)
-{
- m_numbytes = numbytes;
- m_vcsm_handle = vcsm_malloc_cache(numbytes, static_cast<VCSM_CACHE_TYPE_T>(0x80 | static_cast<unsigned>(cached ? VCSM_CACHE_TYPE_HOST : VCSM_CACHE_TYPE_NONE)), const_cast<char*>("CGPUMEM"));
- if (m_vcsm_handle)
- m_vc_handle = vcsm_vc_hdl_from_hdl(m_vcsm_handle);
- if (m_vc_handle)
- m_arm = vcsm_lock(m_vcsm_handle);
- if (m_arm)
- m_vc = mem_lock(g_RBP.GetMBox(), m_vc_handle);
-}
-
-CGPUMEM::~CGPUMEM()
-{
- if (m_vc_handle)
- mem_unlock(g_RBP.GetMBox(), m_vc_handle);
- if (m_arm)
- vcsm_unlock_ptr(m_arm);
- if (m_vcsm_handle)
- vcsm_free(m_vcsm_handle);
-}
-
-// Call this to clean and invalidate a region of memory
-void CGPUMEM::Flush()
-{
- struct vcsm_user_clean_invalid_s iocache = {};
- iocache.s[0].handle = m_vcsm_handle;
- iocache.s[0].cmd = 3; // clean+invalidate
- iocache.s[0].addr = (int) m_arm;
- iocache.s[0].size = m_numbytes;
- vcsm_clean_invalid( &iocache );
-}
-
-AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short video_width, unsigned short video_height)
-{
- AVRpiZcFrameGeometry geo;
- geo.setStripes(1);
- geo.setBitsPerPixel(8);
-
- switch (encoding)
- {
- case MMAL_ENCODING_RGBA: case MMAL_ENCODING_BGRA:
- geo.setBitsPerPixel(32);
- geo.setStrideY(video_width * geo.getBytesPerPixel());
- geo.setHeightY(video_height);
- break;
- case MMAL_ENCODING_RGB24: case MMAL_ENCODING_BGR24:
- geo.setBitsPerPixel(32);
- geo.setStrideY(video_width * geo.getBytesPerPixel());
- geo.setHeightY(video_height);
- break;
- case MMAL_ENCODING_RGB16: case MMAL_ENCODING_BGR16:
- geo.setBitsPerPixel(16);
- geo.setStrideY(video_width * geo.getBytesPerPixel());
- geo.setHeightY(video_height);
- break;
- case MMAL_ENCODING_I420:
- case MMAL_ENCODING_I420_S:
- geo.setStrideY((video_width + 31) & ~31);
- geo.setStrideC(geo.getStrideY() >> 1);
- geo.setHeightY((video_height + 15) & ~15);
- geo.setHeightC(geo.getHeightY() >> 1);
- geo.setPlanesC(2);
- break;
- case MMAL_ENCODING_I420_16:
- geo.setBitsPerPixel(10);
- geo.setStrideY(((video_width + 31) & ~31) * geo.getBytesPerPixel());
- geo.setStrideC(geo.getStrideY() >> 1);
- geo.setHeightY((video_height + 15) & ~15);
- geo.setHeightC(geo.getHeightY() >> 1);
- geo.setPlanesC(2);
- break;
- case MMAL_ENCODING_OPAQUE:
- geo.setStrideY(video_width);
- geo.setHeightY(video_height);
- break;
- case MMAL_ENCODING_YUVUV128:
- {
- VC_IMAGE_T img = {};
- img.type = VC_IMAGE_YUV_UV;
- img.width = video_width;
- img.height = video_height;
- int rc = get_image_params(GetMBox(), &img);
- assert(rc == 0);
- const unsigned int stripe_w = 128;
- geo.setStrideY(stripe_w);
- geo.setStrideC(stripe_w);
- geo.setHeightY(((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w);
- geo.setHeightC(img.pitch / stripe_w - geo.getHeightY());
- geo.setPlanesC(1);
- geo.setStripes((video_width + stripe_w - 1) / stripe_w);
- break;
- }
- case MMAL_ENCODING_YUVUV64_16:
- {
- VC_IMAGE_T img = {};
- img.type = VC_IMAGE_YUV_UV_16;
- img.width = video_width;
- img.height = video_height;
- int rc = get_image_params(GetMBox(), &img);
- assert(rc == 0);
- const unsigned int stripe_w = 128;
- geo.setBitsPerPixel(10);
- geo.setStrideY(stripe_w);
- geo.setStrideC(stripe_w);
- geo.setHeightY(((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w);
- geo.setHeightC(img.pitch / stripe_w - geo.getHeightY());
- geo.setPlanesC(1);
- geo.setStripes((video_width * 2 + stripe_w - 1) / stripe_w);
- break;
- }
- default: assert(0);
- }
- return geo;
-}
diff --git a/xbmc/platform/linux/RBP.h b/xbmc/platform/linux/RBP.h
deleted file mode 100644
index f56e7b5f91..0000000000
--- a/xbmc/platform/linux/RBP.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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
-
-#ifndef USE_VCHIQ_ARM
-#define USE_VCHIQ_ARM
-#endif
-#ifndef __VIDEOCORE4__
-#define __VIDEOCORE4__
-#endif
-#ifndef HAVE_VMCS_CONFIG
-#define HAVE_VMCS_CONFIG
-#endif
-
-#include "DllBCM.h"
-#include "OMXCore.h"
-#include "ServiceBroker.h"
-#include "threads/CriticalSection.h"
-#include "threads/Event.h"
-#include "utils/CPUInfo.h"
-
-class AVRpiZcFrameGeometry
-{
-public:
- unsigned int getStrideY() { return stride_y; }
- unsigned int getHeightY() { return height_y; }
- unsigned int getStrideC() { return stride_c; }
- unsigned int getHeightC() { return height_c; }
- unsigned int getPlanesC() { return planes_c; }
- unsigned int getStripes() { return stripes; }
- unsigned int getBitsPerPixel() { return bits_per_pixel; }
- unsigned int getBytesPerPixel() { return (bits_per_pixel + 7) >> 3; }
- unsigned int getSizeY() { return stride_y * height_y; }
- unsigned int getSizeC() { return stride_c * height_c; }
- unsigned int getSize() { return (getSizeY() + getSizeC() * getPlanesC()) * getStripes(); }
- void setStrideY(unsigned int v) { stride_y = v; }
- void setHeightY(unsigned int v) { height_y = v; }
- void setStrideC(unsigned int v) { stride_c = v; }
- void setHeightC(unsigned int v) { height_c = v; }
- void setPlanesC(unsigned int v) { planes_c = v; }
- void setStripes(unsigned int v) { stripes = v; }
- void setBitsPerPixel(unsigned int v) { bits_per_pixel = v; }
- void setBytesPerPixel(unsigned int v) { bits_per_pixel = v * 8; }
-private:
- unsigned int stride_y = 0;
- unsigned int height_y = 0;
- unsigned int stride_c = 0;
- unsigned int height_c = 0;
- unsigned int planes_c = 0;
- unsigned int stripes = 0;
- unsigned int bits_per_pixel = 0;
-};
-
-class CGPUMEM
-{
-public:
- CGPUMEM(unsigned int numbytes, bool cached = true);
- ~CGPUMEM();
- void Flush();
- void *m_arm = nullptr; // Pointer to memory mapped on ARM side
- int m_vc_handle = 0; // Videocore handle of relocatable memory
- int m_vcsm_handle = 0; // Handle for use by VCSM
- unsigned int m_vc = 0; // Address for use in GPU code
- unsigned int m_numbytes = 0; // Size of memory block
- void *m_opaque = nullptr;
-};
-
-class CRBP
-{
-public:
- CRBP();
- ~CRBP();
-
- bool Initialize();
- void LogFirmwareVersion();
- void Deinitialize();
- int GetArmMem() { return m_arm_mem; }
- int GetGpuMem() { return m_gpu_mem; }
- bool GetCodecMpg2() { return m_codec_mpg2_enabled; }
- int RaspberryPiVersion() { return CServiceBroker::GetCPUInfo()->GetCPUCount() == 1 ? 1 : 2; };
- bool GetCodecWvc1() { return m_codec_wvc1_enabled; }
- void GetDisplaySize(int &width, int &height);
- DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device);
- void CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display);
- int GetGUIResolutionLimit() { return m_gui_resolution_limit; }
- // stride can be null for packed output
- unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true);
- DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; }
- uint32_t LastVsync(int64_t &time);
- uint32_t LastVsync();
- uint32_t WaitVsync(uint32_t target = ~0U);
- void VSyncCallback();
- int GetMBox() { return m_mb; }
- AVRpiZcFrameGeometry GetFrameGeometry(uint32_t encoding, unsigned short video_width, unsigned short video_height);
-
-private:
- DllBcmHost *m_DllBcmHost;
- bool m_initialized;
- bool m_omx_initialized;
- bool m_omx_image_init;
- int m_arm_mem;
- int m_gpu_mem;
- int m_gui_resolution_limit;
- bool m_codec_mpg2_enabled;
- bool m_codec_wvc1_enabled;
- COMXCore *m_OMX;
- DISPMANX_DISPLAY_HANDLE_T m_display;
- CCriticalSection m_vsync_lock;
- XbmcThreads::ConditionVariable m_vsync_cond;
- uint32_t m_vsync_count;
- int64_t m_vsync_time;
- class DllLibOMXCore;
- CCriticalSection m_critSection;
-
- int m_mb;
-};
-
-extern CRBP g_RBP;
diff --git a/xbmc/platform/linux/input/CMakeLists.txt b/xbmc/platform/linux/input/CMakeLists.txt
index bec4224f77..8e69fda1aa 100644
--- a/xbmc/platform/linux/input/CMakeLists.txt
+++ b/xbmc/platform/linux/input/CMakeLists.txt
@@ -6,7 +6,7 @@ if(LIRCCLIENT_FOUND)
list(APPEND HEADERS LIRC.h)
endif()
-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi OR CORE_PLATFORM_NAME_LC STREQUAL gbm)
+if(CORE_PLATFORM_NAME_LC STREQUAL gbm)
if(LIBINPUT_FOUND)
list(APPEND SOURCES LibInputHandler.cpp
LibInputKeyboard.cpp
diff --git a/xbmc/platform/linux/rpi/rpi_user_vcsm.h b/xbmc/platform/linux/rpi/rpi_user_vcsm.h
deleted file mode 100644
index d967e5ceeb..0000000000
--- a/xbmc/platform/linux/rpi/rpi_user_vcsm.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd.
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#pragma once
-
-/* VideoCore Shared Memory - user interface library.
-**
-** This library provides all the necessary abstraction for any application to
-** make use of the shared memory service which is distributed across a kernel
-** driver and a videocore service.
-**
-** It is an application design decision to choose or not to use this service.
-**
-** The logical flow of operations that a user application needs to follow when
-** using this service is:
-**
-** 1) Initialize the service.
-** 2) Allocate shared memory blocks.
-** 3) Start using the allocated blocks.
-** - In order to gain ownership on a block, lock the allocated block,
-** locking a block returns a valid address that the user application
-** can access.
-** - When finished with using the block for the current execution cycle
-** or function, and so when giving up the ownership, unlock the block.
-** 4) A block can be locked/unlocked as many times required - within or outside
-** of - a specific execution context.
-** 5) To completely release an allocated block, free it.
-** 6) If the service is no longer required, terminate it.
-**
-**
-** Some generic considerations:
-
-** Allocating memory blocks.
-**
-** Memory blocks can be allocated in different manners depending on the cache
-** behavior desired. A given block can either be:
-
-** - Allocated in a non cached fashion all the way through host and videocore.
-** - Allocated in a cached fashion on host OR videocore.
-** - Allocated in a cached fashion on host AND videocore.
-**
-** It is an application decision to determine how to allocate a block. Evidently
-** if the application will be doing substantial read/write accesses to a given block,
-** it is recommended to allocate the block at least in a 'host cached' fashion for
-** better results.
-**
-**
-** Locking memory blocks.
-**
-** When the memory block has been allocated in a host cached fashion, locking the
-** memory block (and so taking ownership of it) will trigger a cache invalidation.
-**
-** For the above reason and when using host cached allocation, it is important that
-** an application properly implements the lock/unlock mechanism to ensure cache will
-** stay coherent, otherwise there is no guarantee it will at all be.
-**
-** It is possible to dynamically change the host cache behavior (ie cached or non
-** cached) of a given allocation without needing to free and re-allocate the block.
-** This feature can be useful for such application which requires access to the block
-** only at certain times and not otherwise. By changing the cache behavior dynamically
-** the application can optimize performances for a given duration of use.
-** Such dynamic cache behavior remapping only applies to host cache and not videocore
-** cache. If one requires to change the videocore cache behavior, then a new block
-** must be created to replace the old one.
-**
-** On successful locking, a valid pointer is returned that the application can use
-** to access to data inside the block. There is no guarantee that the pointer will
-** stay valid following the unlock action corresponding to this lock.
-**
-**
-** Unlocking memory blocks.
-**
-** When the memory block has been allocated in a host cached fashion, unlocking the
-** memory block (and so forgiving its ownership) will trigger a cache flush unless
-** explicitly asked not to flush the cache for performances reasons.
-**
-** For the above reason and when using host cached allocation, it is important that
-** an application properly implements the lock/unlock mechanism to ensure cache will
-** stay coherent, otherwise there is no guarantee it will at all be.
-**
-**
-** A complete API is defined below.
-*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* Different status that can be dumped.
-*/
-typedef enum
-{
- VCSM_STATUS_VC_WALK_ALLOC = 0, // Walks *all* the allocation on videocore.
- // Result of the walk is seen in the videocore
- // log.
- VCSM_STATUS_HOST_WALK_MAP, // Walks the *full* mapping allocation on host
- // driver (ie for all processes). Result of
- // the walk is seen in the kernel log.
- VCSM_STATUS_HOST_WALK_PID_MAP, // Walks the per process mapping allocation on host
- // driver (for current process). Result of
- // the walk is seen in the kernel log.
- VCSM_STATUS_HOST_WALK_PID_ALLOC, // Walks the per process host allocation on host
- // driver (for current process). Result of
- // the walk is seen in the kernel log.
- VCSM_STATUS_VC_MAP_ALL, // Equivalent to both VCSM_STATUS_VC_WALK_ALLOC and
- // VCSM_STATUS_HOST_WALK_MAP.
- //
- VCSM_STATUS_NONE, // Must be last - invalid.
-
-} VCSM_STATUS_T;
-
-/* Different kind of cache behavior.
-*/
-typedef enum
-{
- VCSM_CACHE_TYPE_NONE = 0, // No caching applies.
- VCSM_CACHE_TYPE_HOST, // Allocation is cached on host (user space).
- VCSM_CACHE_TYPE_VC, // Allocation is cached on videocore.
- VCSM_CACHE_TYPE_HOST_AND_VC, // Allocation is cached on both host and videocore.
-
-} VCSM_CACHE_TYPE_T;
-
-/* Initialize the vcsm processing.
-**
-** Must be called once before attempting to do anything else.
-**
-** Returns 0 on success, -1 on error.
-*/
-int vcsm_init( void );
-
-
-/* Terminates the vcsm processing.
-**
-** Must be called vcsm services are no longer needed, it will
-** take care of removing any allocation under the current process
-** control if deemed necessary.
-*/
-void vcsm_exit( void );
-
-
-/* Queries the status of the the vcsm.
-**
-** Triggers dump of various kind of information, see the
-** different variants specified in VCSM_STATUS_T.
-**
-** Pid is optional.
-*/
-void vcsm_status( VCSM_STATUS_T status, int pid );
-
-
-/* Allocates a non-cached block of memory of size 'size' via the vcsm memory
-** allocator.
-**
-** Returns: 0 on error
-** a non-zero opaque handle on success.
-**
-** On success, the user must invoke vcsm_lock with the returned opaque
-** handle to gain access to the memory associated with the opaque handle.
-** When finished using the memory, the user calls vcsm_unlock_xx (see those
-** function definition for more details on the one that can be used).
-**
-** A well behaved application should make every attempt to lock/unlock
-** only for the duration it needs to access the memory data associated with
-** the opaque handle.
-*/
-unsigned int vcsm_malloc( unsigned int size, char *name );
-
-
-/* Allocates a cached block of memory of size 'size' via the vcsm memory
-** allocator, the type of caching requested is passed as argument of the
-** function call.
-**
-** Returns: 0 on error
-** a non-zero opaque handle on success.
-**
-** On success, the user must invoke vcsm_lock with the returned opaque
-** handle to gain access to the memory associated with the opaque handle.
-** When finished using the memory, the user calls vcsm_unlock_xx (see those
-** function definition for more details on the one that can be used).
-**
-** A well behaved application should make every attempt to lock/unlock
-** only for the duration it needs to access the memory data associated with
-** the opaque handle.
-*/
-unsigned int vcsm_malloc_cache( unsigned int size, VCSM_CACHE_TYPE_T cache, char *name );
-
-
-/* Shares an allocated block of memory via the vcsm memory allocator.
-**
-** Returns: 0 on error
-** a non-zero opaque handle on success.
-**
-** On success, the user must invoke vcsm_lock with the returned opaque
-** handle to gain access to the memory associated with the opaque handle.
-** When finished using the memory, the user calls vcsm_unlock_xx (see those
-** function definition for more details on the one that can be used).
-**
-** A well behaved application should make every attempt to lock/unlock
-** only for the duration it needs to access the memory data associated with
-** the opaque handle.
-*/
-unsigned int vcsm_malloc_share( unsigned int handle );
-
-
-/* Resizes a block of memory allocated previously by vcsm_alloc.
-**
-** Returns: 0 on success
-** -errno on error.
-**
-** The handle must be unlocked by user prior to attempting any
-** resize action.
-**
-** On error, the original size allocated against the handle
-** remains available the same way it would be following a
-** successful vcsm_malloc.
-*/
-int vcsm_resize( unsigned int handle, unsigned int new_size );
-
-
-/* Frees a block of memory that was successfully allocated by
-** a prior call the vcms_alloc.
-**
-** The handle should be considered invalid upon return from this
-** call.
-**
-** Whether any memory is actually freed up or not as the result of
-** this call will depends on many factors, if all goes well it will
-** be freed. If something goes wrong, the memory will likely end up
-** being freed up as part of the vcsm_exit process. In the end the
-** memory is guaranteed to be freed one way or another.
-*/
-void vcsm_free( unsigned int handle );
-
-
-/* Retrieves a videocore opaque handle from a mapped user address
-** pointer. The videocore handle will correspond to the actual
-** memory mapped in videocore.
-**
-** Returns: 0 on error
-** a non-zero opaque handle on success.
-**
-** Note: the videocore opaque handle is distinct from the user
-** opaque handle (allocated via vcsm_malloc) and it is only
-** significant for such application which knows what to do
-** with it, for the others it is just a number with little
-** use since nothing can be done with it (in particular
-** for safety reason it cannot be used to map anything).
-*/
-unsigned int vcsm_vc_hdl_from_ptr( void *usr_ptr );
-
-
-/* Retrieves a videocore opaque handle from a opaque handle
-** pointer. The videocore handle will correspond to the actual
-** memory mapped in videocore.
-**
-** Returns: 0 on error
-** a non-zero opaque handle on success.
-**
-** Note: the videocore opaque handle is distinct from the user
-** opaque handle (allocated via vcsm_malloc) and it is only
-** significant for such application which knows what to do
-** with it, for the others it is just a number with little
-** use since nothing can be done with it (in particular
-** for safety reason it cannot be used to map anything).
-*/
-unsigned int vcsm_vc_hdl_from_hdl( unsigned int handle );
-
-
-/* Retrieves a user opaque handle from a mapped user address
-** pointer.
-**
-** Returns: 0 on error
-** a non-zero opaque handle on success.
-*/
-unsigned int vcsm_usr_handle( void *usr_ptr );
-
-
-/* Retrieves a mapped user address from an opaque user
-** handle.
-**
-** Returns: 0 on error
-** a non-zero address on success.
-**
-** On success, the address corresponds to the pointer
-** which can access the data allocated via the vcsm_malloc
-** call.
-*/
-void *vcsm_usr_address( unsigned int handle );
-
-
-/* Locks the memory associated with this opaque handle.
-**
-** Returns: NULL on error
-** a valid pointer on success.
-**
-** A user MUST lock the handle received from vcsm_malloc
-** in order to be able to use the memory associated with it.
-**
-** On success, the pointer returned is only valid within
-** the lock content (ie until a corresponding vcsm_unlock_xx
-** is invoked).
-*/
-void *vcsm_lock( unsigned int handle );
-
-
-/* Locks the memory associated with this opaque handle. The lock
-** also gives a chance to update the *host* cache behavior of the
-** allocated buffer if so desired. The *videocore* cache behavior
-** of the allocated buffer cannot be changed by this call and such
-** attempt will be ignored.
-**
-** The system will attempt to honour the cache_update mode request,
-** the cache_result mode will provide the final answer on which cache
-** mode is really in use. Failing to change the cache mode will not
-** result in a failure to lock the buffer as it is an application
-** decision to choose what to do if (cache_result != cache_update)
-**
-** The value returned in cache_result can only be considered valid if
-** the returned pointer is non NULL. The cache_result pointer may be
-** NULL if the application does not care about the actual outcome of
-** its action with regards to the cache behavior change.
-**
-** Returns: NULL on error
-** a valid pointer on success.
-**
-** A user MUST lock the handle received from vcsm_malloc
-** in order to be able to use the memory associated with it.
-**
-** On success, the pointer returned is only valid within
-** the lock content (ie until a corresponding vcsm_unlock_xx
-** is invoked).
-*/
-void *vcsm_lock_cache( unsigned int handle,
- VCSM_CACHE_TYPE_T cache_update,
- VCSM_CACHE_TYPE_T *cache_result );
-
-
-/* Unlocks the memory associated with this user mapped address.
-**
-** Returns: 0 on success
-** -errno on error.
-**
-** After unlocking a mapped address, the user should no longer
-** attempt to reference it.
-*/
-int vcsm_unlock_ptr( void *usr_ptr );
-
-
-/* Unlocks the memory associated with this user mapped address.
-** Apply special processing that would override the otherwise
-** default behavior.
-**
-** If 'cache_no_flush' is specified:
-** Do not flush cache as the result of the unlock (if cache
-** flush was otherwise applicable in this case).
-**
-** Returns: 0 on success
-** -errno on error.
-**
-** After unlocking a mapped address, the user should no longer
-** attempt to reference it.
-*/
-int vcsm_unlock_ptr_sp( void *usr_ptr, int cache_no_flush );
-
-
-/* Unlocks the memory associated with this user opaque handle.
-**
-** Returns: 0 on success
-** -errno on error.
-**
-** After unlocking an opaque handle, the user should no longer
-** attempt to reference the mapped addressed once associated
-** with it.
-*/
-int vcsm_unlock_hdl( unsigned int handle );
-
-
-/* Unlocks the memory associated with this user opaque handle.
-** Apply special processing that would override the otherwise
-** default behavior.
-**
-** If 'cache_no_flush' is specified:
-** Do not flush cache as the result of the unlock (if cache
-** flush was otherwise applicable in this case).
-**
-** Returns: 0 on success
-** -errno on error.
-**
-** After unlocking an opaque handle, the user should no longer
-** attempt to reference the mapped addressed once associated
-** with it.
-*/
-int vcsm_unlock_hdl_sp( unsigned int handle, int cache_no_flush );
-
-/* Clean and/or invalidate the memory associated with this user opaque handle
-**
-** Returns: non-zero on error
-**
-** structure contains a list of flush/invalidate commands. Commands are:
-** 0: nop
-** 1: invalidate given virtual range in L1/L2
-** 2: clean given virtual range in L1/L2
-** 3: clean+invalidate given virtual range in L1/L2
-** 4: flush all L1/L2
-*/
-struct vcsm_user_clean_invalid_s {
- struct {
- unsigned int cmd;
- unsigned int handle;
- unsigned int addr;
- unsigned int size;
- } s[8];
-};
-
-int vcsm_clean_invalid( struct vcsm_user_clean_invalid_s *s );
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/xbmc/platform/linux/test/TestSysfsPath.cpp b/xbmc/platform/linux/test/TestSysfsPath.cpp
index 36613e3305..2c0c27a1a6 100644
--- a/xbmc/platform/linux/test/TestSysfsPath.cpp
+++ b/xbmc/platform/linux/test/TestSysfsPath.cpp
@@ -7,11 +7,11 @@
*/
#include "platform/linux/SysfsPath.h"
+#include "utils/StringUtils.h"
-#include <chrono>
-#include <string>
-#include <sstream>
#include <fstream>
+#include <sstream>
+#include <string>
#include <gtest/gtest.h>
@@ -19,20 +19,14 @@ struct TestSysfsPath : public ::testing::Test
{
std::string GetTestFilePath()
{
- using namespace std::chrono;
-
std::string tmpdir{"/tmp"};
const char *test_tmpdir = getenv("TMPDIR");
+
if (test_tmpdir && test_tmpdir[0] != '\0') {
tmpdir.assign(test_tmpdir);
}
- std::stringstream ss;
- unsigned long long timestamp = duration_cast< nanoseconds >(
- system_clock::now().time_since_epoch()).count();
-
- ss << tmpdir << "/kodi-test-" << timestamp;
- return ss.str();
+ return tmpdir + "/kodi-test-" + StringUtils::CreateUUID();
}
};
diff --git a/xbmc/platform/xbmc.cpp b/xbmc/platform/xbmc.cpp
index e9f39178ca..b910caf7eb 100644
--- a/xbmc/platform/xbmc.cpp
+++ b/xbmc/platform/xbmc.cpp
@@ -8,10 +8,6 @@
#include "Application.h"
-#ifdef TARGET_RASPBERRY_PI
-#include "platform/linux/RBP.h"
-#endif
-
#ifdef TARGET_WINDOWS_DESKTOP
#include "platform/win32/IMMNotificationClient.h"
#include <mmdeviceapi.h>
@@ -36,11 +32,7 @@ extern "C" int XBMC_Run(bool renderGUI, const CAppParamParser &params)
return status;
}
-#ifdef TARGET_RASPBERRY_PI
- if(!g_RBP.Initialize())
- return false;
- g_RBP.LogFirmwareVersion();
-#elif defined(TARGET_ANDROID)
+#if defined(TARGET_ANDROID)
CXBMCApp::get()->Initialize();
#endif
@@ -82,9 +74,7 @@ extern "C" int XBMC_Run(bool renderGUI, const CAppParamParser &params)
}
#endif
-#ifdef TARGET_RASPBERRY_PI
- g_RBP.Deinitialize();
-#elif defined(TARGET_ANDROID)
+#if defined(TARGET_ANDROID)
CXBMCApp::get()->Deinitialize();
#endif
diff --git a/xbmc/pvr/epg/Epg.cpp b/xbmc/pvr/epg/Epg.cpp
index 01faa576b3..e58ddad501 100644
--- a/xbmc/pvr/epg/Epg.cpp
+++ b/xbmc/pvr/epg/Epg.cpp
@@ -291,7 +291,7 @@ std::vector<std::shared_ptr<CPVREpgInfoTag>> CPVREpg::GetTags() const
return m_tags.GetAllTags();
}
-bool CPVREpg::Persist(const std::shared_ptr<CPVREpgDatabase>& database, bool bQueueWrite)
+bool CPVREpg::QueuePersistQuery(const std::shared_ptr<CPVREpgDatabase>& database)
{
// Note: It is guaranteed that both this EPG instance and database instance are already
// locked when this method gets called! No additional locking is needed here!
@@ -313,15 +313,15 @@ bool CPVREpg::Persist(const std::shared_ptr<CPVREpgDatabase>& database, bool bQu
}
if (m_tags.NeedsSave())
- m_tags.Persist(!bQueueWrite);
+ m_tags.QueuePersistQuery();
if (m_bUpdateLastScanTime)
- database->PersistLastEpgScanTime(m_iEpgID, m_lastScanTime, bQueueWrite);
+ database->QueuePersistLastEpgScanTimeQuery(m_iEpgID, m_lastScanTime);
m_bChanged = false;
m_bUpdateLastScanTime = false;
- return bQueueWrite || database->CommitInsertQueries();
+ return true;
}
bool CPVREpg::Delete(const std::shared_ptr<CPVREpgDatabase>& database)
diff --git a/xbmc/pvr/epg/Epg.h b/xbmc/pvr/epg/Epg.h
index 63412945a5..55f7bb65d4 100644
--- a/xbmc/pvr/epg/Epg.h
+++ b/xbmc/pvr/epg/Epg.h
@@ -203,12 +203,11 @@ namespace PVR
const CDateTime& maxEventStart) const;
/*!
- * @brief Persist this table in the given database
+ * @brief Write the query to persist data into given database's queue
* @param database The database.
- * @param bQueueWrite Don't execute the query immediately but queue it if true.
- * @return True if the table was persisted, false otherwise.
+ * @return True on success, false otherwise.
*/
- bool Persist(const std::shared_ptr<CPVREpgDatabase>& database, bool bQueueWrite);
+ bool QueuePersistQuery(const std::shared_ptr<CPVREpgDatabase>& database);
/*!
* @brief Delete this table from the given database
diff --git a/xbmc/pvr/epg/EpgContainer.cpp b/xbmc/pvr/epg/EpgContainer.cpp
index 430361bfac..ac8b0392af 100644
--- a/xbmc/pvr/epg/EpgContainer.cpp
+++ b/xbmc/pvr/epg/EpgContainer.cpp
@@ -312,14 +312,26 @@ bool CPVREpgContainer::PersistAll(unsigned int iMaxTimeslice) const
CLog::Log(LOGDEBUG, "EPG Container: Persisting events for channel '%s'...",
epg->GetChannelData()->ChannelName().c_str());
- bReturn &= epg->Persist(database, true);
+ bReturn &= epg->QueuePersistQuery(database);
+
+ size_t queryCount = database->GetInsertQueriesCount() + database->GetDeleteQueriesCount();
+ if (queryCount > 10000)
+ {
+ CLog::Log(LOGDEBUG, LOGEPG, "EPG Container: committing %d queries in loop.", queryCount);
+ database->CommitDeleteQueries();
+ database->CommitInsertQueries();
+ CLog::Log(LOGDEBUG, LOGEPG, "EPG Container: committed %d queries in loop.", queryCount);
+ }
}
epg->Unlock();
}
if (bReturn)
+ {
+ database->CommitDeleteQueries();
database->CommitInsertQueries();
+ }
database->Unlock();
}
diff --git a/xbmc/pvr/epg/EpgDatabase.cpp b/xbmc/pvr/epg/EpgDatabase.cpp
index b0388fe17b..0c3d844af8 100644
--- a/xbmc/pvr/epg/EpgDatabase.cpp
+++ b/xbmc/pvr/epg/EpgDatabase.cpp
@@ -290,7 +290,7 @@ bool CPVREpgDatabase::Delete(const CPVREpg& table)
return DeleteValues("epg", filter);
}
-bool CPVREpgDatabase::Delete(const CPVREpgInfoTag& tag)
+bool CPVREpgDatabase::QueueDeleteTagQuery(const CPVREpgInfoTag& tag)
{
/* tag without a database ID was not persisted */
if (tag.DatabaseID() <= 0)
@@ -300,7 +300,10 @@ bool CPVREpgDatabase::Delete(const CPVREpgInfoTag& tag)
CSingleLock lock(m_critSection);
filter.AppendWhere(PrepareSQL("idBroadcast = %u", tag.DatabaseID()));
- return DeleteValues("epgtags", filter);
+
+ std::string strQuery;
+ BuildSQL(PrepareSQL("DELETE FROM %s ", "epgtags"), filter, strQuery);
+ return QueueDeleteQuery(strQuery);
}
std::vector<std::shared_ptr<CPVREpg>> CPVREpgDatabase::GetAll()
@@ -894,9 +897,9 @@ std::vector<std::shared_ptr<CPVREpgInfoTag>> CPVREpgDatabase::GetEpgTagsByMinEnd
return {};
}
-bool CPVREpgDatabase::DeleteEpgTagsByMinEndMaxStartTime(int iEpgID,
- const CDateTime& minEndTime,
- const CDateTime& maxStartTime)
+bool CPVREpgDatabase::QueueDeleteEpgTagsByMinEndMaxStartTimeQuery(int iEpgID,
+ const CDateTime& minEndTime,
+ const CDateTime& maxStartTime)
{
time_t minEnd;
minEndTime.GetAsTime(minEnd);
@@ -910,7 +913,10 @@ bool CPVREpgDatabase::DeleteEpgTagsByMinEndMaxStartTime(int iEpgID,
filter.AppendWhere(PrepareSQL("idEpg = %u AND iEndTime >= %u AND iStartTime <= %u", iEpgID,
static_cast<unsigned int>(minEnd),
static_cast<unsigned int>(maxStart)));
- return DeleteValues("epgtags", filter);
+
+ std::string strQuery;
+ BuildSQL("DELETE FROM epgtags", filter, strQuery);
+ return QueueDeleteQuery(strQuery);
}
std::vector<std::shared_ptr<CPVREpgInfoTag>> CPVREpgDatabase::GetAllEpgTags(int iEpgID)
@@ -960,15 +966,13 @@ bool CPVREpgDatabase::GetLastEpgScanTime(int iEpgId, CDateTime* lastScan)
return bReturn;
}
-bool CPVREpgDatabase::PersistLastEpgScanTime(int iEpgId,
- const CDateTime& lastScanTime,
- bool bQueueWrite)
+bool CPVREpgDatabase::QueuePersistLastEpgScanTimeQuery(int iEpgId, const CDateTime& lastScanTime)
{
CSingleLock lock(m_critSection);
std::string strQuery = PrepareSQL("REPLACE INTO lastepgscan(idEpg, sLastScan) VALUES (%u, '%s');",
iEpgId, lastScanTime.GetAsDBDateTime().c_str());
- return bQueueWrite ? QueueInsertQuery(strQuery) : ExecuteQuery(strQuery);
+ return QueueInsertQuery(strQuery);
}
int CPVREpgDatabase::Persist(const CPVREpg& epg, bool bQueueWrite)
@@ -1022,14 +1026,12 @@ bool CPVREpgDatabase::DeleteEpgTags(int iEpgId)
return DeleteValues("epgtags", filter);
}
-int CPVREpgDatabase::Persist(const CPVREpgInfoTag& tag, bool bSingleUpdate /* = true */)
+bool CPVREpgDatabase::QueuePersistQuery(const CPVREpgInfoTag& tag)
{
- int iReturn(-1);
-
if (tag.EpgID() <= 0)
{
CLog::LogF(LOGERROR, "Tag '%s' does not have a valid table", tag.Title().c_str());
- return iReturn;
+ return false;
}
time_t iStartTime, iEndTime;
@@ -1081,18 +1083,8 @@ int CPVREpgDatabase::Persist(const CPVREpgInfoTag& tag, bool bSingleUpdate /* =
tag.UniqueBroadcastID(), iBroadcastId);
}
- if (bSingleUpdate)
- {
- if (ExecuteQuery(strQuery))
- iReturn = static_cast<int>(m_pDS->lastinsertid());
- }
- else
- {
- QueueInsertQuery(strQuery);
- iReturn = 0;
- }
-
- return iReturn;
+ QueueInsertQuery(strQuery);
+ return true;
}
int CPVREpgDatabase::GetLastEPGId()
diff --git a/xbmc/pvr/epg/EpgDatabase.h b/xbmc/pvr/epg/EpgDatabase.h
index 0753d94a5d..99960cdfb0 100644
--- a/xbmc/pvr/epg/EpgDatabase.h
+++ b/xbmc/pvr/epg/EpgDatabase.h
@@ -88,11 +88,11 @@ namespace PVR
bool Delete(const CPVREpg& table);
/*!
- * @brief Remove a single EPG entry.
- * @param tag The entry to remove.
- * @return True if it was removed successfully, false otherwise.
+ * @brief Write the query to delete the given EPG tag to db query queue.
+ * @param tag The EPG tag to remove.
+ * @return True on success, false otherwise.
*/
- bool Delete(const CPVREpgInfoTag& tag);
+ bool QueueDeleteTagQuery(const CPVREpgInfoTag& tag);
/*!
* @brief Get all EPG tables from the database. Does not get the EPG tables' entries.
@@ -199,15 +199,16 @@ namespace PVR
int iEpgID, const CDateTime& minEndTime, const CDateTime& maxStartTime);
/*!
- * @brief Delete all EPG tags in range of given EPG id, min end time and max start time.
+ * @brief Write the query to delete all EPG tags in range of given EPG id, min end time and max
+ * start time to db query queue. .
* @param iEpgID The ID of the EPG for the tags to delete.
* @param minEndTime The min end time for the tags to delete.
* @param maxStartTime The max start time for the tags to delete.
- * @return True on success, false otherwise.
+ * @return True if it was removed or queued successfully, false otherwise.
*/
- bool DeleteEpgTagsByMinEndMaxStartTime(int iEpgID,
- const CDateTime& minEndTime,
- const CDateTime& maxStartTime);
+ bool QueueDeleteEpgTagsByMinEndMaxStartTimeQuery(int iEpgID,
+ const CDateTime& minEndTime,
+ const CDateTime& maxStartTime);
/*!
* @brief Get the last stored EPG scan time.
@@ -218,19 +219,18 @@ namespace PVR
bool GetLastEpgScanTime(int iEpgId, CDateTime* lastScan);
/*!
- * @brief Update the last scan time.
+ * @brief Write the query to update the last scan time for the given EPG to db query queue.
* @param iEpgId The table to update the time for.
* @param lastScanTime The time to write to the database.
- * @param bQueueWrite Don't execute the query immediately but queue it if true.
- * @return True if it was updated successfully, false otherwise.
+ * @return True on success, false otherwise.
*/
- bool PersistLastEpgScanTime(int iEpgId, const CDateTime& lastScanTime, bool bQueueWrite);
+ bool QueuePersistLastEpgScanTimeQuery(int iEpgId, const CDateTime& lastScanTime);
/*!
* @brief Persist an EPG table. It's entries are not persisted.
* @param epg The table to persist.
- * @param bQueueWrite Don't execute the query immediately but queue it if true.
- * @return The database ID of this entry or 0 if bSingleUpdate is false and the query was queued.
+ * @param bQueueWrite If true, don't execute the query immediately but queue it.
+ * @return The database ID of this entry or 0 if bQueueWrite is false and the query was queued.
*/
int Persist(const CPVREpg& epg, bool bQueueWrite);
@@ -250,12 +250,11 @@ namespace PVR
bool DeleteEpgTags(int iEpgId);
/*!
- * @brief Persist an infotag.
+ * @brief Write the query to persist the given EPG tag to db query queue.
* @param tag The tag to persist.
- * @param bSingleUpdate If true, this is a single update and the query will be executed immediately.
- * @return The database ID of this entry or 0 if bSingleUpdate is false and the query was queued.
+ * @return True on success, false otherwise.
*/
- int Persist(const CPVREpgInfoTag& tag, bool bSingleUpdate = true);
+ bool QueuePersistQuery(const CPVREpgInfoTag& tag);
/*!
* @return Last EPG id in the database
diff --git a/xbmc/pvr/epg/EpgInfoTag.cpp b/xbmc/pvr/epg/EpgInfoTag.cpp
index 492f450b8e..933e63ce5c 100644
--- a/xbmc/pvr/epg/EpgInfoTag.cpp
+++ b/xbmc/pvr/epg/EpgInfoTag.cpp
@@ -550,26 +550,15 @@ bool CPVREpgInfoTag::Update(const CPVREpgInfoTag& tag, bool bUpdateBroadcastId /
return bChanged;
}
-bool CPVREpgInfoTag::Persist(const std::shared_ptr<CPVREpgDatabase>& database, bool bSingleUpdate /* = true */)
+bool CPVREpgInfoTag::QueuePersistQuery(const std::shared_ptr<CPVREpgDatabase>& database)
{
- bool bReturn = false;
-
if (!database)
{
CLog::LogF(LOGERROR, "Could not open the EPG database");
- return bReturn;
- }
-
- int iId = database->Persist(*this, bSingleUpdate);
- if (iId >= 0)
- {
- bReturn = true;
-
- if (iId > 0)
- m_iDatabaseID = iId;
+ return false;
}
- return bReturn;
+ return database->QueuePersistQuery(*this);
}
std::vector<PVR_EDL_ENTRY> CPVREpgInfoTag::GetEdl() const
diff --git a/xbmc/pvr/epg/EpgInfoTag.h b/xbmc/pvr/epg/EpgInfoTag.h
index 3b26789ccb..7cbd41f02a 100644
--- a/xbmc/pvr/epg/EpgInfoTag.h
+++ b/xbmc/pvr/epg/EpgInfoTag.h
@@ -342,12 +342,11 @@ namespace PVR
bool IsPlayable() const;
/*!
- * @brief Persist this tag in the given database.
+ * @brief Write query to persist this tag in the query queue of the given database.
* @param database The database.
- * @param bSingleUpdate True if this is a single update, false if more updates will follow.
- * @return True if the tag was persisted correctly, false otherwise.
+ * @return True on success, false otherwise.
*/
- bool Persist(const std::shared_ptr<CPVREpgDatabase>& database, bool bSingleUpdate = true);
+ bool QueuePersistQuery(const std::shared_ptr<CPVREpgDatabase>& database);
/*!
* @brief Update the information in this tag with the info in the given tag.
diff --git a/xbmc/pvr/epg/EpgTagsContainer.cpp b/xbmc/pvr/epg/EpgTagsContainer.cpp
index e7f9fd55e4..618bd8838d 100644
--- a/xbmc/pvr/epg/EpgTagsContainer.cpp
+++ b/xbmc/pvr/epg/EpgTagsContainer.cpp
@@ -87,6 +87,45 @@ void ResolveConflictingTags(const std::shared_ptr<CPVREpgInfoTag>& changedTag,
}
}
+bool FixOverlap(const std::shared_ptr<CPVREpgInfoTag>& previousTag,
+ const std::shared_ptr<CPVREpgInfoTag>& currentTag)
+{
+ if (!previousTag)
+ return true;
+
+ if (previousTag->EndAsUTC() >= currentTag->EndAsUTC())
+ {
+ // delete the current tag. it's completely overlapped
+ CLog::LogF(LOGWARNING,
+ "Erasing completely overlapped event from EPG timeline "
+ "(%u - %s - %s - %s) "
+ "(%u - %s - %s - %s).",
+ previousTag->UniqueBroadcastID(), previousTag->Title().c_str(),
+ previousTag->StartAsUTC().GetAsDBDateTime(),
+ previousTag->EndAsUTC().GetAsDBDateTime(), currentTag->UniqueBroadcastID(),
+ currentTag->Title().c_str(), currentTag->StartAsUTC().GetAsDBDateTime(),
+ currentTag->EndAsUTC().GetAsDBDateTime());
+
+ return false;
+ }
+ else if (previousTag->EndAsUTC() > currentTag->StartAsUTC())
+ {
+ // fix the end time of the predecessor of the event
+ CLog::LogF(LOGWARNING,
+ "Fixing partly overlapped event in EPG timeline "
+ "(%u - %s - %s - %s) "
+ "(%u - %s - %s - %s).",
+ previousTag->UniqueBroadcastID(), previousTag->Title().c_str(),
+ previousTag->StartAsUTC().GetAsDBDateTime(),
+ previousTag->EndAsUTC().GetAsDBDateTime(), currentTag->UniqueBroadcastID(),
+ currentTag->Title().c_str(), currentTag->StartAsUTC().GetAsDBDateTime(),
+ currentTag->EndAsUTC().GetAsDBDateTime());
+
+ previousTag->SetEndFromUTC(currentTag->StartAsUTC());
+ }
+ return true;
+}
+
} // unnamed namespace
bool CPVREpgTagsContainer::UpdateEntries(const CPVREpgTagsContainer& tags)
@@ -174,50 +213,35 @@ void CPVREpgTagsContainer::FixOverlappingEvents(
for (auto it = tags.begin(); it != tags.end();)
{
const std::shared_ptr<CPVREpgInfoTag> currentTag = *it;
- if (!previousTag)
+ if (FixOverlap(previousTag, currentTag))
{
previousTag = currentTag;
++it;
- continue;
}
-
- if (previousTag->EndAsUTC() >= currentTag->EndAsUTC())
+ else
{
- // delete the current tag. it's completely overlapped
- CLog::LogF(LOGWARNING,
- "Erasing completely overlapped event from EPG timeline "
- "(%u - %s - %s - %s) "
- "(%u - %s - %s - %s).",
- previousTag->UniqueBroadcastID(), previousTag->Title().c_str(),
- previousTag->StartAsUTC().GetAsDBDateTime(),
- previousTag->EndAsUTC().GetAsDBDateTime(), currentTag->UniqueBroadcastID(),
- currentTag->Title().c_str(), currentTag->StartAsUTC().GetAsDBDateTime(),
- currentTag->EndAsUTC().GetAsDBDateTime());
-
it = tags.erase(it);
m_tagsCache->Reset();
}
- else if (previousTag->EndAsUTC() > currentTag->StartAsUTC())
+ }
+}
+
+void CPVREpgTagsContainer::FixOverlappingEvents(
+ std::map<CDateTime, std::shared_ptr<CPVREpgInfoTag>>& tags) const
+{
+ std::shared_ptr<CPVREpgInfoTag> previousTag;
+ for (auto it = tags.begin(); it != tags.end();)
+ {
+ const std::shared_ptr<CPVREpgInfoTag> currentTag = (*it).second;
+ if (FixOverlap(previousTag, currentTag))
{
- // fix the end time of the predecessor of the event
- CLog::LogF(LOGWARNING,
- "Fixing partly overlapped event in EPG timeline "
- "(%u - %s - %s - %s) "
- "(%u - %s - %s - %s).",
- previousTag->UniqueBroadcastID(), previousTag->Title().c_str(),
- previousTag->StartAsUTC().GetAsDBDateTime(),
- previousTag->EndAsUTC().GetAsDBDateTime(), currentTag->UniqueBroadcastID(),
- currentTag->Title().c_str(), currentTag->StartAsUTC().GetAsDBDateTime(),
- currentTag->EndAsUTC().GetAsDBDateTime());
-
- previousTag->SetEndFromUTC(currentTag->StartAsUTC());
previousTag = currentTag;
++it;
}
else
{
- previousTag = currentTag;
- ++it;
+ it = tags.erase(it);
+ m_tagsCache->Reset();
}
}
}
@@ -510,8 +534,7 @@ std::vector<std::shared_ptr<CPVREpgInfoTag>> CPVREpgTagsContainer::GetAllTags()
for (const auto& tag : m_changedTags)
tags.emplace_back(tag.second);
- if (!tags.empty())
- FixOverlappingEvents(tags);
+ FixOverlappingEvents(tags);
}
else
{
@@ -572,7 +595,7 @@ bool CPVREpgTagsContainer::NeedsSave() const
return !m_changedTags.empty() || !m_deletedTags.empty();
}
-void CPVREpgTagsContainer::Persist(bool bCommit)
+void CPVREpgTagsContainer::QueuePersistQuery()
{
if (m_database)
{
@@ -582,24 +605,23 @@ void CPVREpgTagsContainer::Persist(bool bCommit)
m_changedTags.size(), m_deletedTags.size());
for (const auto& tag : m_deletedTags)
- m_database->Delete(*tag.second);
+ m_database->QueueDeleteTagQuery(*tag.second);
m_deletedTags.clear();
+ FixOverlappingEvents(m_changedTags);
+
for (const auto& tag : m_changedTags)
{
// remove any conflicting events from database before persisting the new event
- m_database->DeleteEpgTagsByMinEndMaxStartTime(m_iEpgID, tag.second->StartAsUTC() + ONE_SECOND,
- tag.second->EndAsUTC() - ONE_SECOND);
+ m_database->QueueDeleteEpgTagsByMinEndMaxStartTimeQuery(
+ m_iEpgID, tag.second->StartAsUTC() + ONE_SECOND, tag.second->EndAsUTC() - ONE_SECOND);
- tag.second->Persist(m_database, false);
+ tag.second->QueuePersistQuery(m_database);
}
m_changedTags.clear();
- if (bCommit)
- m_database->CommitInsertQueries();
-
m_database->Unlock();
}
}
diff --git a/xbmc/pvr/epg/EpgTagsContainer.h b/xbmc/pvr/epg/EpgTagsContainer.h
index 6a3ca24ce5..3900f28b83 100644
--- a/xbmc/pvr/epg/EpgTagsContainer.h
+++ b/xbmc/pvr/epg/EpgTagsContainer.h
@@ -159,10 +159,9 @@ public:
bool NeedsSave() const;
/*!
- * @brief Persist this container in its database.
- * @param bCommit Whether to commit the data.
+ * @brief Write the query to persist data into database's queue
*/
- void Persist(bool bCommit);
+ void QueuePersistQuery();
/*!
* @brief Delete this container from its database.
@@ -198,6 +197,7 @@ private:
* @param tags The events to check/fix.
*/
void FixOverlappingEvents(std::vector<std::shared_ptr<CPVREpgInfoTag>>& tags) const;
+ void FixOverlappingEvents(std::map<CDateTime, std::shared_ptr<CPVREpgInfoTag>>& tags) const;
int m_iEpgID = 0;
std::shared_ptr<CPVREpgChannelData> m_channelData;
diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp
index 7db981a1a0..b517846eaf 100644
--- a/xbmc/pvr/recordings/PVRRecording.cpp
+++ b/xbmc/pvr/recordings/PVRRecording.cpp
@@ -581,6 +581,16 @@ CDateTime CPVRRecording::FirstAired() const
return m_firstAired;
}
+int CPVRRecording::GetYear() const
+{
+ return m_premiered.GetYear();
+}
+
+bool CPVRRecording::HasYear() const
+{
+ return m_premiered.IsValid();
+}
+
bool CPVRRecording::IsNew() const
{
return (m_iFlags & PVR_RECORDING_FLAG_IS_NEW) > 0;
diff --git a/xbmc/pvr/recordings/PVRRecording.h b/xbmc/pvr/recordings/PVRRecording.h
index 2043d66834..b9f7389b51 100644
--- a/xbmc/pvr/recordings/PVRRecording.h
+++ b/xbmc/pvr/recordings/PVRRecording.h
@@ -334,6 +334,18 @@ namespace PVR
CDateTime FirstAired() const;
/*!
+ * @brief Get the premiere year of this event.
+ * @return The premiere year
+ */
+ int GetYear() const override;
+
+ /*!
+ * @brief Check if the premiere year of this event is valid
+ * @return True if the event has as valid premiere date, false otherwise
+ */
+ bool HasYear() const override;
+
+ /*!
* @brief Check whether this recording will be flagged as new.
* @return True if this recording will be flagged as new, false otherwise
*/
diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp
index b3905039c3..be337833c2 100644
--- a/xbmc/rendering/gles/RenderSystemGLES.cpp
+++ b/xbmc/rendering/gles/RenderSystemGLES.cpp
@@ -71,8 +71,7 @@ bool CRenderSystemGLES::InitRenderSystem()
m_RenderExtensions += " ";
-//! @todo remove TARGET_RASPBERRY_PI when Raspberry Pi updates their GL headers
-#if defined(GL_KHR_debug) && defined(TARGET_LINUX) && !defined(TARGET_RASPBERRY_PI)
+#if defined(GL_KHR_debug) && defined(TARGET_LINUX)
if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_openGlDebugging)
{
if (IsExtSupported("GL_KHR_debug"))
diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp
index 66f574ab97..9ffc1606b9 100644
--- a/xbmc/settings/AdvancedSettings.cpp
+++ b/xbmc/settings/AdvancedSettings.cpp
@@ -184,7 +184,7 @@ void CAdvancedSettings::Initialize()
m_videoCleanDateTimeRegExp = "(.*[^ _\\,\\.\\(\\)\\[\\]\\-])[ _\\.\\(\\)\\[\\]\\-]+(19[0-9][0-9]|20[0-9][0-9])([ _\\,\\.\\(\\)\\[\\]\\-]|[^0-9]$)?";
m_videoCleanStringRegExps.clear();
- m_videoCleanStringRegExps.emplace_back("[ _\\,\\.\\(\\)\\[\\]\\-](ac3|dts|custom|dc|remastered|divx|divx5|dsr|dsrip|dutch|dvd|dvd5|dvd9|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|extended|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|3d|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|cd[1-9]|\\[.*\\])([ _\\,\\.\\(\\)\\[\\]\\-]|$)");
+ m_videoCleanStringRegExps.emplace_back("[ _\\,\\.\\(\\)\\[\\]\\-](aka|ac3|dts|custom|dc|remastered|divx|divx5|dsr|dsrip|dutch|dvd|dvd5|dvd9|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|extended|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|3d|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|cd[1-9]|\\[.*\\])([ _\\,\\.\\(\\)\\[\\]\\-]|$)");
m_videoCleanStringRegExps.emplace_back("(\\[.*\\])");
// this vector will be inserted at the end to
diff --git a/xbmc/settings/SettingPath.cpp b/xbmc/settings/SettingPath.cpp
index 9258a0fe07..378d53b149 100644
--- a/xbmc/settings/SettingPath.cpp
+++ b/xbmc/settings/SettingPath.cpp
@@ -65,9 +65,13 @@ bool CSettingPath::Deserialize(const TiXmlNode *node, bool update /* = false */)
auto source = sources->FirstChild("source");
while (source != nullptr)
{
- std::string strSource = source->FirstChild()->ValueStr();
- if (!strSource.empty())
- m_sources.push_back(strSource);
+ auto child = source->FirstChild();
+ if (child != nullptr)
+ {
+ std::string strSource = child->ValueStr();
+ if (!strSource.empty())
+ m_sources.push_back(strSource);
+ }
source = source->NextSibling("source");
}
diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp
index 8680b105ae..8036a90868 100644
--- a/xbmc/settings/Settings.cpp
+++ b/xbmc/settings/Settings.cpp
@@ -33,9 +33,6 @@
#if defined(TARGET_DARWIN_EMBEDDED)
#include "SettingAddon.h"
#endif
-#if defined(TARGET_RASPBERRY_PI)
-#include "platform/linux/RBP.h"
-#endif
#include "powermanagement/PowerTypes.h"
#include "profiles/ProfileManager.h"
#include "ServiceBroker.h"
@@ -142,7 +139,6 @@ const std::string CSettings::SETTING_VIDEOPLAYER_USEVDPAUMPEG4 = "videoplayer.us
const std::string CSettings::SETTING_VIDEOPLAYER_USEVDPAUVC1 = "videoplayer.usevdpauvc1";
const std::string CSettings::SETTING_VIDEOPLAYER_USEDXVA2 = "videoplayer.usedxva2";
const std::string CSettings::SETTING_VIDEOPLAYER_USEVTB = "videoplayer.usevtb";
-const std::string CSettings::SETTING_VIDEOPLAYER_USEMMAL = "videoplayer.usemmal";
const std::string CSettings::SETTING_VIDEOPLAYER_USEPRIMEDECODER = "videoplayer.useprimedecoder";
const std::string CSettings::SETTING_VIDEOPLAYER_USESTAGEFRIGHT = "videoplayer.usestagefright";
const std::string CSettings::SETTING_VIDEOPLAYER_LIMITGUIUPDATE = "videoplayer.limitguiupdate";
@@ -625,11 +621,6 @@ bool CSettings::InitializeDefinitions()
#elif defined(TARGET_ANDROID)
if (CFile::Exists(SETTINGS_XML_FOLDER "android.xml") && !Initialize(SETTINGS_XML_FOLDER "android.xml"))
CLog::Log(LOGFATAL, "Unable to load android-specific settings definitions");
-#elif defined(TARGET_RASPBERRY_PI)
- if (CFile::Exists(SETTINGS_XML_FOLDER "rbp.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp.xml"))
- CLog::Log(LOGFATAL, "Unable to load rbp-specific settings definitions");
- if (g_RBP.RaspberryPiVersion() > 1 && CFile::Exists(SETTINGS_XML_FOLDER "rbp2.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp2.xml"))
- CLog::Log(LOGFATAL, "Unable to load rbp2-specific settings definitions");
#elif defined(TARGET_FREEBSD)
if (CFile::Exists(SETTINGS_XML_FOLDER "freebsd.xml") && !Initialize(SETTINGS_XML_FOLDER "freebsd.xml"))
CLog::Log(LOGFATAL, "Unable to load freebsd-specific settings definitions");
diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h
index 220bbd716e..518d3c19cc 100644
--- a/xbmc/settings/Settings.h
+++ b/xbmc/settings/Settings.h
@@ -107,7 +107,6 @@ public:
static const std::string SETTING_VIDEOPLAYER_USEVDPAUVC1;
static const std::string SETTING_VIDEOPLAYER_USEDXVA2;
static const std::string SETTING_VIDEOPLAYER_USEVTB;
- static const std::string SETTING_VIDEOPLAYER_USEMMAL;
static const std::string SETTING_VIDEOPLAYER_USEPRIMEDECODER;
static const std::string SETTING_VIDEOPLAYER_USESTAGEFRIGHT;
static const std::string SETTING_VIDEOPLAYER_LIMITGUIUPDATE;
diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
index 790854be43..3bb2846f02 100644
--- a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
+++ b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
@@ -39,6 +39,7 @@
#define SETTING_CONTAINS_SINGLE_ITEM "containssingleitem"
#define SETTING_EXCLUDE "exclude"
#define SETTING_NO_UPDATING "noupdating"
+#define SETTING_ALL_EXTERNAL_AUDIO "allexternalaudio"
using namespace ADDON;
@@ -65,6 +66,7 @@ void CGUIDialogContentSettings::SetScanSettings(const VIDEO::SScanSettings &scan
m_exclude = scanSettings.exclude;
m_containsSingleItem = scanSettings.parent_name_root;
m_noUpdating = scanSettings.noupdate;
+ m_allExternalAudio = scanSettings.m_allExtAudio;
}
bool CGUIDialogContentSettings::Show(ADDON::ScraperPtr& scraper, CONTENT_TYPE content /* = CONTENT_NONE */)
@@ -97,6 +99,8 @@ bool CGUIDialogContentSettings::Show(ADDON::ScraperPtr& scraper, VIDEO::SScanSet
scraper = dialog->GetScraper();
content = dialog->GetContent();
+ settings.m_allExtAudio = dialog->GetUseAllExternalAudio();
+
if (scraper == NULL || content == CONTENT_NONE)
settings.exclude = dialog->GetExclude();
else
@@ -166,6 +170,8 @@ void CGUIDialogContentSettings::OnSettingChanged(std::shared_ptr<const CSetting>
}
else if (settingId == SETTING_EXCLUDE)
m_exclude = std::static_pointer_cast<const CSettingBool>(setting)->GetValue();
+ else if (settingId == SETTING_ALL_EXTERNAL_AUDIO)
+ m_allExternalAudio = std::static_pointer_cast<const CSettingBool>(setting)->GetValue();
}
void CGUIDialogContentSettings::OnSettingAction(std::shared_ptr<const CSetting> setting)
@@ -334,6 +340,8 @@ void CGUIDialogContentSettings::InitializeSettings()
{
AddToggle(groupDetails, SETTING_CONTAINS_SINGLE_ITEM, 20379, SettingLevel::Basic, m_containsSingleItem, false, m_showScanSettings);
AddToggle(groupDetails, SETTING_NO_UPDATING, 20432, SettingLevel::Basic, m_noUpdating, false, m_showScanSettings);
+ AddToggle(groupDetails, SETTING_ALL_EXTERNAL_AUDIO, 39120, SettingLevel::Basic,
+ m_allExternalAudio, false, m_showScanSettings);
break;
}
@@ -344,6 +352,8 @@ void CGUIDialogContentSettings::InitializeSettings()
std::shared_ptr<CSettingBool> settingScanRecursive = AddToggle(groupDetails, SETTING_SCAN_RECURSIVE, 20346, SettingLevel::Basic, m_scanRecursive, false, m_showScanSettings);
std::shared_ptr<CSettingBool> settingContainsSingleItem = AddToggle(groupDetails, SETTING_CONTAINS_SINGLE_ITEM, 20383, SettingLevel::Basic, m_containsSingleItem, false, m_showScanSettings);
AddToggle(groupDetails, SETTING_NO_UPDATING, 20432, SettingLevel::Basic, m_noUpdating, false, m_showScanSettings);
+ AddToggle(groupDetails, SETTING_ALL_EXTERNAL_AUDIO, 39120, SettingLevel::Basic,
+ m_allExternalAudio, false, m_showScanSettings);
// define an enable dependency with (m_useDirectoryNames && !m_containsSingleItem) || !m_useDirectoryNames
CSettingDependency dependencyScanRecursive(SettingDependencyType::Enable, GetSettingsManager());
@@ -376,6 +386,8 @@ void CGUIDialogContentSettings::InitializeSettings()
case CONTENT_NONE:
default:
AddToggle(groupDetails, SETTING_EXCLUDE, 20380, SettingLevel::Basic, m_exclude, false, !m_showScanSettings);
+ AddToggle(groupDetails, SETTING_ALL_EXTERNAL_AUDIO, 39120, SettingLevel::Basic,
+ m_allExternalAudio, false, !m_showScanSettings);
break;
}
}
diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.h b/xbmc/settings/dialogs/GUIDialogContentSettings.h
index 18770ac1b9..97f7dbe30b 100644
--- a/xbmc/settings/dialogs/GUIDialogContentSettings.h
+++ b/xbmc/settings/dialogs/GUIDialogContentSettings.h
@@ -40,6 +40,7 @@ public:
bool GetContainsSingleItem() const { return m_containsSingleItem; }
bool GetExclude() const { return m_exclude; }
bool GetNoUpdating() const { return m_noUpdating; }
+ bool GetUseAllExternalAudio() const { return m_allExternalAudio; }
static bool Show(ADDON::ScraperPtr& scraper, CONTENT_TYPE content = CONTENT_NONE);
static bool Show(ADDON::ScraperPtr& scraper, VIDEO::SScanSettings& settings, CONTENT_TYPE content = CONTENT_NONE);
@@ -85,4 +86,5 @@ private:
bool m_containsSingleItem = false;
bool m_exclude = false;
bool m_noUpdating = false;
+ bool m_allExternalAudio = false;
};
diff --git a/xbmc/test/TestDateTime.cpp b/xbmc/test/TestDateTime.cpp
index cac90fcd4b..3abc3c43e4 100644
--- a/xbmc/test/TestDateTime.cpp
+++ b/xbmc/test/TestDateTime.cpp
@@ -37,12 +37,17 @@ TEST_F(TestDateTime, FileTimeOperators)
CDateTime dateTime1(1991, 5, 14, 12, 34, 56);
CDateTime dateTime2(1991, 5, 14, 12, 34, 57);
- KODI::TIME::FileTime fileTime;
- dateTime2.GetAsTimeStamp(fileTime);
+ KODI::TIME::FileTime fileTime1;
+ KODI::TIME::FileTime fileTime2;
+
+ dateTime1.GetAsTimeStamp(fileTime1);
+ dateTime2.GetAsTimeStamp(fileTime2);
+
+ CDateTime dateTime3(fileTime1);
- EXPECT_TRUE(dateTime1 < fileTime);
- EXPECT_FALSE(dateTime1 > fileTime);
- EXPECT_FALSE(dateTime1 == fileTime);
+ EXPECT_TRUE(dateTime3 < fileTime2);
+ EXPECT_FALSE(dateTime3 > fileTime2);
+ EXPECT_FALSE(dateTime3 == fileTime2);
}
TEST_F(TestDateTime, SystemTimeOperators)
diff --git a/xbmc/utils/EGLUtils.cpp b/xbmc/utils/EGLUtils.cpp
index 01df4ba7e7..0d7c23891c 100644
--- a/xbmc/utils/EGLUtils.cpp
+++ b/xbmc/utils/EGLUtils.cpp
@@ -21,19 +21,6 @@
namespace
{
-//! @todo remove when Raspberry Pi updates their EGL headers
-#ifndef EGL_NO_CONFIG_KHR
-#define EGL_NO_CONFIG_KHR static_cast<EGLConfig>(0)
-#endif
-#ifndef EGL_CONTEXT_PRIORITY_LEVEL_IMG
-#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
-#endif
-#ifndef EGL_CONTEXT_PRIORITY_HIGH_IMG
-#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
-#endif
-#ifndef EGL_CONTEXT_PRIORITY_MEDIUM_IMG
-#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
-#endif
#define X(VAL) std::make_pair(VAL, #VAL)
std::map<EGLint, const char*> eglAttributes =
@@ -97,21 +84,21 @@ std::map<EGLenum, const char*> eglErrors =
std::map<EGLint, const char*> eglErrorType =
{
-//! @todo remove when Raspberry Pi updates their EGL headers
-#if !defined(TARGET_RASPBERRY_PI)
X(EGL_DEBUG_MSG_CRITICAL_KHR),
X(EGL_DEBUG_MSG_ERROR_KHR),
X(EGL_DEBUG_MSG_WARN_KHR),
X(EGL_DEBUG_MSG_INFO_KHR),
-#endif
};
#undef X
} // namespace
-//! @todo remove when Raspberry Pi updates their EGL headers
-#if !defined(TARGET_RASPBERRY_PI)
-void EglErrorCallback(EGLenum error, const char* command, EGLint messageType, EGLLabelKHR threadLabel, EGLLabelKHR objectLabel, const char* message)
+void EglErrorCallback(EGLenum error,
+ const char* command,
+ EGLint messageType,
+ EGLLabelKHR threadLabel,
+ EGLLabelKHR objectLabel,
+ const char* message)
{
std::string errorStr;
std::string typeStr;
@@ -130,7 +117,6 @@ void EglErrorCallback(EGLenum error, const char* command, EGLint messageType, EG
CLog::Log(LOGDEBUG, "EGL Debugging:\nError: {}\nCommand: {}\nType: {}\nMessage: {}", errorStr, command, typeStr, message);
}
-#endif
std::set<std::string> CEGLUtils::GetClientExtensions()
{
@@ -185,8 +171,6 @@ void CEGLUtils::Log(int logLevel, const std::string& what)
CEGLContextUtils::CEGLContextUtils(EGLenum platform, std::string const& platformExtension)
: m_platform{platform}
{
-//! @todo remove when Raspberry Pi updates their EGL headers
-#if !defined(TARGET_RASPBERRY_PI)
if (CEGLUtils::HasClientExtension("EGL_KHR_debug"))
{
auto eglDebugMessageControl = CEGLUtils::GetRequiredProcAddress<PFNEGLDEBUGMESSAGECONTROLKHRPROC>("eglDebugMessageControlKHR");
@@ -199,7 +183,6 @@ CEGLContextUtils::CEGLContextUtils(EGLenum platform, std::string const& platform
eglDebugMessageControl(EglErrorCallback, eglDebugAttribs);
}
-#endif
m_platformSupported = CEGLUtils::HasClientExtension("EGL_EXT_platform_base") && CEGLUtils::HasClientExtension(platformExtension);
}
@@ -414,14 +397,11 @@ bool CEGLContextUtils::CreateContext(CEGLAttributesVec contextAttribs)
if (CEGLUtils::HasExtension(m_eglDisplay, "EGL_IMG_context_priority"))
contextAttribs.Add({{EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG}});
-//! @todo remove when Raspberry Pi updates their EGL headers
-#if !defined(TARGET_RASPBERRY_PI)
if (CEGLUtils::HasExtension(m_eglDisplay, "EGL_KHR_create_context") &&
CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_openGlDebugging)
{
contextAttribs.Add({{EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR}});
}
-#endif
m_eglContext = eglCreateContext(m_eglDisplay, eglConfig,
EGL_NO_CONTEXT, contextAttribs.Get());
diff --git a/xbmc/utils/GLUtils.cpp b/xbmc/utils/GLUtils.cpp
index be94eb5a2c..1ef804709f 100644
--- a/xbmc/utils/GLUtils.cpp
+++ b/xbmc/utils/GLUtils.cpp
@@ -39,41 +39,35 @@ std::map<GLenum, const char*> glErrors =
#endif
};
-std::map<GLenum, const char*> glErrorSource =
-{
-//! @todo remove TARGET_RASPBERRY_PI when Raspberry Pi updates their GL headers
-#if defined(HAS_GLES) && defined(TARGET_LINUX) && !defined(TARGET_RASPBERRY_PI)
- X(GL_DEBUG_SOURCE_API_KHR),
- X(GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR),
- X(GL_DEBUG_SOURCE_SHADER_COMPILER_KHR),
- X(GL_DEBUG_SOURCE_THIRD_PARTY_KHR),
- X(GL_DEBUG_SOURCE_APPLICATION_KHR),
- X(GL_DEBUG_SOURCE_OTHER_KHR),
+std::map<GLenum, const char*> glErrorSource = {
+#if defined(HAS_GLES) && defined(TARGET_LINUX)
+ X(GL_DEBUG_SOURCE_API_KHR),
+ X(GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR),
+ X(GL_DEBUG_SOURCE_SHADER_COMPILER_KHR),
+ X(GL_DEBUG_SOURCE_THIRD_PARTY_KHR),
+ X(GL_DEBUG_SOURCE_APPLICATION_KHR),
+ X(GL_DEBUG_SOURCE_OTHER_KHR),
#endif
};
-std::map<GLenum, const char*> glErrorType =
-{
-//! @todo remove TARGET_RASPBERRY_PI when Raspberry Pi updates their GL headers
-#if defined(HAS_GLES) && defined(TARGET_LINUX) && !defined(TARGET_RASPBERRY_PI)
- X(GL_DEBUG_TYPE_ERROR_KHR),
- X(GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR),
- X(GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR),
- X(GL_DEBUG_TYPE_PORTABILITY_KHR),
- X(GL_DEBUG_TYPE_PERFORMANCE_KHR),
- X(GL_DEBUG_TYPE_OTHER_KHR),
- X(GL_DEBUG_TYPE_MARKER_KHR),
+std::map<GLenum, const char*> glErrorType = {
+#if defined(HAS_GLES) && defined(TARGET_LINUX)
+ X(GL_DEBUG_TYPE_ERROR_KHR),
+ X(GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR),
+ X(GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR),
+ X(GL_DEBUG_TYPE_PORTABILITY_KHR),
+ X(GL_DEBUG_TYPE_PERFORMANCE_KHR),
+ X(GL_DEBUG_TYPE_OTHER_KHR),
+ X(GL_DEBUG_TYPE_MARKER_KHR),
#endif
};
-std::map<GLenum, const char*> glErrorSeverity =
-{
-//! @todo remove TARGET_RASPBERRY_PI when Raspberry Pi updates their GL headers
-#if defined(HAS_GLES) && defined(TARGET_LINUX) && !defined(TARGET_RASPBERRY_PI)
- X(GL_DEBUG_SEVERITY_HIGH_KHR),
- X(GL_DEBUG_SEVERITY_MEDIUM_KHR),
- X(GL_DEBUG_SEVERITY_LOW_KHR),
- X(GL_DEBUG_SEVERITY_NOTIFICATION_KHR),
+std::map<GLenum, const char*> glErrorSeverity = {
+#if defined(HAS_GLES) && defined(TARGET_LINUX)
+ X(GL_DEBUG_SEVERITY_HIGH_KHR),
+ X(GL_DEBUG_SEVERITY_MEDIUM_KHR),
+ X(GL_DEBUG_SEVERITY_LOW_KHR),
+ X(GL_DEBUG_SEVERITY_NOTIFICATION_KHR),
#endif
};
#undef X
diff --git a/xbmc/utils/RecentlyAddedJob.cpp b/xbmc/utils/RecentlyAddedJob.cpp
index b6374fc6a8..93344a984f 100644
--- a/xbmc/utils/RecentlyAddedJob.cpp
+++ b/xbmc/utils/RecentlyAddedJob.cpp
@@ -75,6 +75,7 @@ bool CRecentlyAddedJob::UpdateVideo()
home->SetProperty("LatestMovie." + value + ".Thumb" , item->GetArt("thumb"));
home->SetProperty("LatestMovie." + value + ".Fanart" , item->GetArt("fanart"));
+ home->SetProperty("LatestMovie." + value + ".Poster" , item->GetArt("poster"));
}
}
for (; i < NUM_ITEMS; ++i)
@@ -89,6 +90,7 @@ bool CRecentlyAddedJob::UpdateVideo()
home->SetProperty("LatestMovie." + value + ".Path" , "");
home->SetProperty("LatestMovie." + value + ".Trailer" , "");
home->SetProperty("LatestMovie." + value + ".Fanart" , "");
+ home->SetProperty("LatestMovie." + value + ".Poster" , "");
}
i = 0;
diff --git a/xbmc/utils/SystemInfo.cpp b/xbmc/utils/SystemInfo.cpp
index a29ece96ce..92d2c19c93 100644
--- a/xbmc/utils/SystemInfo.cpp
+++ b/xbmc/utils/SystemInfo.cpp
@@ -1176,9 +1176,7 @@ std::string CSysInfo::GetUserAgent()
result += " " + linuxOSName + "/" + GetOsVersion();
#endif
-#ifdef TARGET_RASPBERRY_PI
- result += " HW_RaspberryPi/1.0";
-#elif defined (TARGET_DARWIN_EMBEDDED)
+#if defined(TARGET_DARWIN_IOS)
std::string iDevVer;
if (iDevStrDigit == std::string::npos)
iDevVer = "0.0";
diff --git a/xbmc/utils/log.cpp b/xbmc/utils/log.cpp
index 7fb87feed2..b1f221380d 100644
--- a/xbmc/utils/log.cpp
+++ b/xbmc/utils/log.cpp
@@ -179,7 +179,7 @@ bool CLog::IsLogLevelLogged(int loglevel)
if (m_logLevel <= LOG_LEVEL_NONE)
return false;
- return (loglevel & LOGMASK) >= LOGNOTICE;
+ return (loglevel & LOGMASK) >= LOGINFO;
}
bool CLog::CanLogComponent(uint32_t component) const
@@ -245,13 +245,11 @@ spdlog::level::level_enum CLog::MapLogLevel(int level)
case LOGDEBUG:
return spdlog::level::debug;
case LOGINFO:
- case LOGNOTICE:
return spdlog::level::info;
case LOGWARNING:
return spdlog::level::warn;
case LOGERROR:
return spdlog::level::err;
- case LOGSEVERE:
case LOGFATAL:
return spdlog::level::critical;
case LOGNONE:
diff --git a/xbmc/utils/test/TestSystemInfo.cpp b/xbmc/utils/test/TestSystemInfo.cpp
index 1f2b0a10f3..4ee3256362 100644
--- a/xbmc/utils/test/TestSystemInfo.cpp
+++ b/xbmc/utils/test/TestSystemInfo.cpp
@@ -239,10 +239,6 @@ TEST_F(TestSystemInfo, GetUserAgent)
#endif // defined(TARGET_LINUX)
#endif // defined(TARGET_POSIX)
-#ifdef TARGET_RASPBERRY_PI
- EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find(" XBMC_HW_RaspberryPi/")) << "'GetUserAgent()' must contain ' XBMC_HW_RaspberryPi/'";
-#endif // TARGET_RASPBERRY_PI
-
EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find(" App_Bitness/")) << "'GetUserAgent()' must contain ' App_Bitness/'";
EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find(" Version/")) << "'GetUserAgent()' must contain ' Version/'";
}
diff --git a/xbmc/utils/test/Testlog.cpp b/xbmc/utils/test/Testlog.cpp
index 7405c02f59..8391da123e 100644
--- a/xbmc/utils/test/Testlog.cpp
+++ b/xbmc/utils/test/Testlog.cpp
@@ -43,10 +43,8 @@ TEST_F(Testlog, Log)
CLog::Log(LOGDEBUG, "debug log message");
CLog::Log(LOGINFO, "info log message");
- CLog::Log(LOGNOTICE, "notice log message");
CLog::Log(LOGWARNING, "warning log message");
CLog::Log(LOGERROR, "error log message");
- CLog::Log(LOGSEVERE, "severe log message");
CLog::Log(LOGFATAL, "fatal log message");
CLog::Log(LOGNONE, "none type log message");
CServiceBroker::GetLogging().Uninitialize();
@@ -66,14 +64,10 @@ TEST_F(Testlog, Log)
EXPECT_GE(regex.RegFind(logstring), 0);
EXPECT_TRUE(regex.RegComp(".*INFO <general>: info log message.*"));
EXPECT_GE(regex.RegFind(logstring), 0);
- EXPECT_TRUE(regex.RegComp(".*INFO <general>: notice log message.*"));
- EXPECT_GE(regex.RegFind(logstring), 0);
EXPECT_TRUE(regex.RegComp(".*WARNING <general>: warning log message.*"));
EXPECT_GE(regex.RegFind(logstring), 0);
EXPECT_TRUE(regex.RegComp(".*ERROR <general>: error log message.*"));
EXPECT_GE(regex.RegFind(logstring), 0);
- EXPECT_TRUE(regex.RegComp(".*FATAL <general>: severe log message.*"));
- EXPECT_GE(regex.RegFind(logstring), 0);
EXPECT_TRUE(regex.RegComp(".*FATAL <general>: fatal log message.*"));
EXPECT_GE(regex.RegFind(logstring), 0);
EXPECT_TRUE(regex.RegComp(".*OFF <general>: none type log message.*"));
diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp
index 10e4afa22f..b3ae9348e3 100644
--- a/xbmc/video/VideoDatabase.cpp
+++ b/xbmc/video/VideoDatabase.cpp
@@ -122,7 +122,10 @@ void CVideoDatabase::CreateTables()
m_pDS->exec("CREATE TABLE writer_link(actor_id INTEGER, media_id INTEGER, media_type TEXT)");
CLog::Log(LOGINFO, "create path table");
- m_pDS->exec("CREATE TABLE path ( idPath integer primary key, strPath text, strContent text, strScraper text, strHash text, scanRecursive integer, useFolderNames bool, strSettings text, noUpdate bool, exclude bool, dateAdded text, idParentPath integer)");
+ m_pDS->exec(
+ "CREATE TABLE path ( idPath integer primary key, strPath text, strContent text, strScraper "
+ "text, strHash text, scanRecursive integer, useFolderNames bool, strSettings text, noUpdate "
+ "bool, exclude bool, allAudio bool, dateAdded text, idParentPath integer)");
CLog::Log(LOGINFO, "create files table");
m_pDS->exec("CREATE TABLE files ( idFile integer primary key, idPath integer, strFilename text, playCount integer, lastPlayed text, dateAdded text)");
@@ -5038,16 +5041,26 @@ void CVideoDatabase::SetScraperForPath(const std::string& filePath, const Scrape
std::string strSQL;
if (settings.exclude)
{ //NB See note in ::GetScraperForPath about strContent=='none'
- strSQL=PrepareSQL("update path set strContent='', strScraper='', scanRecursive=0, useFolderNames=0, strSettings='', noUpdate=0 , exclude=1 where idPath=%i", idPath);
+ strSQL = PrepareSQL(
+ "UPDATE path SET strContent='', strScraper='', scanRecursive=0, useFolderNames=0, "
+ "strSettings='', noUpdate=0, exclude=1, allAudio=%i WHERE idPath=%i",
+ settings.m_allExtAudio, idPath);
}
else if(!scraper)
{ // catch clearing content, but not excluding
- strSQL=PrepareSQL("update path set strContent='', strScraper='', scanRecursive=0, useFolderNames=0, strSettings='', noUpdate=0, exclude=0 where idPath=%i", idPath);
+ strSQL = PrepareSQL(
+ "UPDATE path SET strContent='', strScraper='', scanRecursive=0, useFolderNames=0, "
+ "strSettings='', noUpdate=0, exclude=0, allAudio=%i WHERE idPath=%i",
+ settings.m_allExtAudio, idPath);
}
else
{
std::string content = TranslateContent(scraper->Content());
- strSQL=PrepareSQL("update path set strContent='%s', strScraper='%s', scanRecursive=%i, useFolderNames=%i, strSettings='%s', noUpdate=%i, exclude=0 where idPath=%i", content.c_str(), scraper->ID().c_str(),settings.recurse,settings.parent_name,scraper->GetPathSettings().c_str(),settings.noupdate, idPath);
+ strSQL = PrepareSQL(
+ "UPDATE path SET strContent='%s', strScraper='%s', scanRecursive=%i, useFolderNames=%i, "
+ "strSettings='%s', noUpdate=%i, exclude=0, allAudio=%i WHERE idPath=%i",
+ content.c_str(), scraper->ID().c_str(), settings.recurse, settings.parent_name,
+ scraper->GetPathSettings().c_str(), settings.noupdate, settings.m_allExtAudio, idPath);
}
m_pDS->exec(strSQL);
}
@@ -5668,11 +5681,14 @@ void CVideoDatabase::UpdateTables(int iVersion)
}
m_pDS->close();
}
+
+ if (iVersion < 119)
+ m_pDS->exec("ALTER TABLE path ADD allAudio bool");
}
int CVideoDatabase::GetSchemaVersion() const
{
- return 118;
+ return 119;
}
bool CVideoDatabase::LookupByFolders(const std::string &path, bool shows)
@@ -7800,7 +7816,10 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe
if (idPath > -1)
{
- std::string strSQL=PrepareSQL("select path.strContent,path.strScraper,path.scanRecursive,path.useFolderNames,path.strSettings,path.noUpdate,path.exclude from path where path.idPath=%i",idPath);
+ std::string strSQL = PrepareSQL(
+ "SELECT path.strContent, path.strScraper, path.scanRecursive, path.useFolderNames, "
+ "path.strSettings, path.noUpdate, path.exclude, path.allAudio FROM path WHERE idPath=%i",
+ idPath);
m_pDS->query( strSQL );
}
@@ -7809,6 +7828,8 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe
if (!m_pDS->eof())
{ // path is stored in db
+ settings.m_allExtAudio = m_pDS->fv("path.allAudio").get_asBool();
+
if (m_pDS->fv("path.exclude").get_asBool())
{
settings.exclude = true;
@@ -7849,13 +7870,17 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe
{
iFound++;
- std::string strSQL=PrepareSQL("select path.strContent,path.strScraper,path.scanRecursive,path.useFolderNames,path.strSettings,path.noUpdate, path.exclude from path where strPath='%s'",strParent.c_str());
+ std::string strSQL =
+ PrepareSQL("SELECT path.strContent, path.strScraper, path.scanRecursive, "
+ "path.useFolderNames, path.strSettings, path.noUpdate, path.exclude, "
+ "path.allAudio FROM path WHERE strPath='%s'",
+ strParent.c_str());
m_pDS->query(strSQL);
CONTENT_TYPE content = CONTENT_NONE;
if (!m_pDS->eof())
{
-
+ settings.m_allExtAudio = m_pDS->fv("path.allAudio").get_asBool();
std::string strcontent = m_pDS->fv("path.strContent").get_asString();
StringUtils::ToLower(strcontent);
if (m_pDS->fv("path.exclude").get_asBool())
@@ -7926,6 +7951,20 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe
return ScraperPtr();
}
+bool CVideoDatabase::GetUseAllExternalAudioForVideo(const std::string& videoPath)
+{
+ // Find longest configured source path for given video path
+ std::string strSQL = PrepareSQL("SELECT allAudio FROM path WHERE allAudio IS NOT NULL AND "
+ "instr('%s', strPath) = 1 ORDER BY length(strPath) DESC LIMIT 1",
+ videoPath.c_str());
+ m_pDS->query(strSQL);
+
+ if (!m_pDS->eof())
+ return m_pDS->fv("allAudio").get_asBool();
+
+ return false;
+}
+
std::string CVideoDatabase::GetContentForPath(const std::string& strPath)
{
SScanSettings settings;
diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h
index 1480e4f9a3..cb5afae8a4 100644
--- a/xbmc/video/VideoDatabase.h
+++ b/xbmc/video/VideoDatabase.h
@@ -874,6 +874,7 @@ public:
void ClearMovieSet(int idMovie);
void SetMovieSet(int idMovie, int idSet);
bool SetVideoUserRating(int dbId, int rating, const MediaType& mediaType);
+ bool GetUseAllExternalAudioForVideo(const std::string& videoPath);
protected:
int GetMovieId(const std::string& strFilenameAndPath);
diff --git a/xbmc/video/VideoInfoScanner.h b/xbmc/video/VideoInfoScanner.h
index 2d9966124d..7c221aaf3d 100644
--- a/xbmc/video/VideoInfoScanner.h
+++ b/xbmc/video/VideoInfoScanner.h
@@ -26,12 +26,21 @@ namespace VIDEO
typedef struct SScanSettings
{
- SScanSettings() { parent_name = parent_name_root = noupdate = exclude = false; recurse = 1;}
+ SScanSettings()
+ {
+ parent_name = false;
+ parent_name_root = false;
+ noupdate = false;
+ exclude = false;
+ m_allExtAudio = false;
+ recurse = 1;
+ }
bool parent_name; /* use the parent dirname as name of lookup */
bool parent_name_root; /* use the name of directory where scan started as name for files in that dir */
int recurse; /* recurse into sub folders (indicate levels) */
bool noupdate; /* exclude from update library function */
bool exclude; /* exclude this path from scraping */
+ bool m_allExtAudio; /* treat all audio files in video directory as external tracks */
} SScanSettings;
class CVideoInfoScanner : public CInfoScanner
diff --git a/xbmc/video/VideoInfoTag.h b/xbmc/video/VideoInfoTag.h
index 7dad34d551..197a6aa6eb 100644
--- a/xbmc/video/VideoInfoTag.h
+++ b/xbmc/video/VideoInfoTag.h
@@ -80,8 +80,8 @@ public:
const std::map<std::string, std::string>& GetUniqueIDs() const;
const std::string& GetDefaultUniqueID() const;
bool HasUniqueID() const;
- bool HasYear() const;
- int GetYear() const;
+ virtual bool HasYear() const;
+ virtual int GetYear() const;
bool HasPremiered() const;
const CDateTime& GetPremiered() const;
const CDateTime& GetFirstAired() const;
diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
index 7d3097df82..28d5b6b0b1 100644
--- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
@@ -320,10 +320,6 @@ void CGUIDialogVideoSettings::InitializeSettings()
entries.push_back(TranslatableIntegerSettingOption(16327, VS_INTERLACEMETHOD_VAAPI_BOB));
entries.push_back(TranslatableIntegerSettingOption(16328, VS_INTERLACEMETHOD_VAAPI_MADI));
entries.push_back(TranslatableIntegerSettingOption(16329, VS_INTERLACEMETHOD_VAAPI_MACI));
- entries.push_back(TranslatableIntegerSettingOption(16330, VS_INTERLACEMETHOD_MMAL_ADVANCED));
- entries.push_back(TranslatableIntegerSettingOption(16331, VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF));
- entries.push_back(TranslatableIntegerSettingOption(16332, VS_INTERLACEMETHOD_MMAL_BOB));
- entries.push_back(TranslatableIntegerSettingOption(16333, VS_INTERLACEMETHOD_MMAL_BOB_HALF));
entries.push_back(TranslatableIntegerSettingOption(16320, VS_INTERLACEMETHOD_DXVA_AUTO));
/* remove unsupported methods */
diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp
index 023460b10a..974d88ab46 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.cpp
+++ b/xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -40,6 +40,7 @@
#include "settings/MediaSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
+#include "settings/SettingUtils.h"
#include "settings/dialogs/GUIDialogContentSettings.h"
#include "storage/MediaManager.h"
#include "utils/FileExtensionProvider.h"
@@ -73,6 +74,11 @@ using namespace KODI::MESSAGING;
#define PROPERTY_GROUP_BY "group.by"
#define PROPERTY_GROUP_MIXED "group.mixed"
+static constexpr int SETTING_AUTOPLAYNEXT_MUSICVIDEOS = 0;
+static constexpr int SETTING_AUTOPLAYNEXT_EPISODES = 2;
+static constexpr int SETTING_AUTOPLAYNEXT_MOVIES = 3;
+static constexpr int SETTING_AUTOPLAYNEXT_UNCATEGORIZED = 4;
+
CGUIWindowVideoBase::CGUIWindowVideoBase(int id, const std::string &xmlFile)
: CGUIMediaWindow(id, xmlFile.c_str())
{
@@ -915,10 +921,28 @@ void CGUIWindowVideoBase::GetContextButtons(int itemNumber, CContextButtons &but
(!item->HasProperty("IsPlayable") || item->GetProperty("IsPlayable").asBoolean()) &&
m_vecItems->Size() > 1 && itemNumber < m_vecItems->Size() - 1)
{
- if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOPLAYER_AUTOPLAYNEXTITEM))
- buttons.Add(CONTEXT_BUTTON_PLAY_AND_QUEUE, 13412);
- else
+ int settingValue = SETTING_AUTOPLAYNEXT_UNCATEGORIZED;
+
+ if (item->IsVideoDb() && item->HasVideoInfoTag())
+ {
+ const std::string mediaType = item->GetVideoInfoTag()->m_type;
+
+ if (mediaType == MediaTypeMusicVideo)
+ settingValue = SETTING_AUTOPLAYNEXT_MUSICVIDEOS;
+ else if (mediaType == MediaTypeEpisode)
+ settingValue = SETTING_AUTOPLAYNEXT_EPISODES;
+ else if (mediaType == MediaTypeMovie)
+ settingValue = SETTING_AUTOPLAYNEXT_MOVIES;
+ }
+
+ const auto setting = std::dynamic_pointer_cast<CSettingList>(
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(
+ CSettings::SETTING_VIDEOPLAYER_AUTOPLAYNEXTITEM));
+
+ if (setting && CSettingUtils::FindIntInList(setting, settingValue))
buttons.Add(CONTEXT_BUTTON_PLAY_ONLY_THIS, 13434);
+ else
+ buttons.Add(CONTEXT_BUTTON_PLAY_AND_QUEUE, 13412);
}
if (item->IsSmartPlayList() || m_vecItems->IsSmartPlayList())
buttons.Add(CONTEXT_BUTTON_EDIT_SMART_PLAYLIST, 586);
diff --git a/xbmc/windowing/gbm/DRMUtils.cpp b/xbmc/windowing/gbm/DRMUtils.cpp
index a2da4ce437..cf05ea5188 100644
--- a/xbmc/windowing/gbm/DRMUtils.cpp
+++ b/xbmc/windowing/gbm/DRMUtils.cpp
@@ -16,6 +16,7 @@
#include "windowing/GraphicContext.h"
#include <errno.h>
+#include <sstream>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -922,3 +923,66 @@ bool CDRMUtils::CheckConnector(int connector_id)
return finalConnectionState == DRM_MODE_CONNECTED;
}
+
+std::string CDRMUtils::FourCCToString(uint32_t fourcc)
+{
+ std::stringstream ss;
+ ss << static_cast<char>((fourcc & 0x000000FF));
+ ss << static_cast<char>((fourcc & 0x0000FF00) >> 8);
+ ss << static_cast<char>((fourcc & 0x00FF0000) >> 16);
+ ss << static_cast<char>((fourcc & 0xFF000000) >> 24);
+
+ return ss.str();
+}
+
+bool plane::SupportsFormat(uint32_t format)
+{
+ for (uint32_t i = 0; i < plane->count_formats; i++)
+ if (plane->formats[i] == format)
+ return true;
+
+ return false;
+}
+
+bool plane::SupportsFormatAndModifier(uint32_t format, uint64_t modifier)
+{
+ /*
+ * Some broadcom modifiers have parameters encoded which need to be
+ * masked out before comparing with reported modifiers.
+ */
+ if (modifier >> 56 == DRM_FORMAT_MOD_VENDOR_BROADCOM)
+ modifier = fourcc_mod_broadcom_mod(modifier);
+
+ if (modifier == DRM_FORMAT_MOD_LINEAR)
+ {
+ if (!SupportsFormat(format))
+ {
+ CLog::Log(LOGDEBUG, "plane::{} - format not supported: {}", __FUNCTION__,
+ CDRMUtils::FourCCToString(format));
+ return false;
+ }
+ }
+ else
+ {
+ auto formatModifiers = &modifiers_map[format];
+ if (formatModifiers->empty())
+ {
+ CLog::Log(LOGDEBUG, "plane::{} - format not supported: {}", __FUNCTION__,
+ CDRMUtils::FourCCToString(format));
+ return false;
+ }
+
+ auto formatModifier = std::find(formatModifiers->begin(), formatModifiers->end(), modifier);
+ if (formatModifier == formatModifiers->end())
+ {
+ CLog::Log(LOGDEBUG, "plane::{} - modifier ({:#x}) not supported for format ({})",
+ __FUNCTION__, modifier, CDRMUtils::FourCCToString(format));
+ return false;
+ }
+ }
+
+ CLog::Log(LOGDEBUG, "plane::{} - found plane format ({}) and modifier ({:#x})", __FUNCTION__,
+ CDRMUtils::FourCCToString(format), modifier);
+
+ return true;
+}
diff --git a/xbmc/windowing/gbm/DRMUtils.h b/xbmc/windowing/gbm/DRMUtils.h
index 5c2174c9ea..a79436f93e 100644
--- a/xbmc/windowing/gbm/DRMUtils.h
+++ b/xbmc/windowing/gbm/DRMUtils.h
@@ -51,7 +51,11 @@ struct plane : drm_object
void SetFormat(uint32_t newFormat) { format = newFormat; }
uint32_t GetFormat() { return format; }
+ bool SupportsFormatAndModifier(uint32_t format, uint64_t modifier);
+
private:
+ bool SupportsFormat(uint32_t format);
+
uint32_t format{DRM_FORMAT_XRGB8888};
};
@@ -109,6 +113,7 @@ public:
static uint32_t FourCCWithAlpha(uint32_t fourcc);
static uint32_t FourCCWithoutAlpha(uint32_t fourcc);
+ static std::string FourCCToString(uint32_t fourcc);
protected:
bool OpenDrm(bool needConnector);
diff --git a/xbmc/windowing/rpi/CMakeLists.txt b/xbmc/windowing/rpi/CMakeLists.txt
deleted file mode 100644
index f42c6419fc..0000000000
--- a/xbmc/windowing/rpi/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-set(SOURCES WinSystemRpi.cpp
- RPIUtils.cpp
- VideoSyncPi.cpp)
-
-set(HEADERS WinSystemRpi.h
- RPIUtils.h
- VideoSyncPi.h)
-
-if(OPENGLES_FOUND)
- list(APPEND SOURCES WinSystemRpiGLESContext.cpp)
- list(APPEND HEADERS WinSystemRpiGLESContext.h)
-endif()
-
-core_add_library(windowing_Rpi)
diff --git a/xbmc/windowing/rpi/RPIUtils.cpp b/xbmc/windowing/rpi/RPIUtils.cpp
deleted file mode 100644
index c7a3a719f8..0000000000
--- a/xbmc/windowing/rpi/RPIUtils.cpp
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Copyright (C) 2011-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "RPIUtils.h"
-
-#include "ServiceBroker.h"
-#include "guilib/StereoscopicsManager.h"
-#include "guilib/gui3d.h"
-#include "rendering/RenderSystem.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "utils/StringUtils.h"
-#include "utils/log.h"
-#include "windowing/GraphicContext.h"
-
-#include "platform/linux/DllBCM.h"
-#include "platform/linux/RBP.h"
-
-#include <cassert>
-#include <math.h>
-
-#ifndef __VIDEOCORE4__
-#define __VIDEOCORE4__
-#endif
-
-#define __VCCOREVER__ 0x04000000
-
-#define IS_WIDESCREEN(m) ( m == 3 || m == 7 || m == 9 || \
- m == 11 || m == 13 || m == 15 || m == 18 || m == 22 || \
- m == 24 || m == 26 || m == 28 || m == 30 || m == 36 || \
- m == 38 || m == 43 || m == 45 || m == 49 || m == 51 || \
- m == 53 || m == 55 || m == 57 || m == 59)
-
-#define MAKEFLAGS(group, mode, interlace) \
- ( ( (mode)<<24 ) | ( (group)<<16 ) | \
- ( (interlace) != 0 ? D3DPRESENTFLAG_INTERLACED : D3DPRESENTFLAG_PROGRESSIVE) | \
- ( ((group) == HDMI_RES_GROUP_CEA && IS_WIDESCREEN(mode) ) ? D3DPRESENTFLAG_WIDESCREEN : 0) )
-
-#define GETFLAGS_GROUP(f) ( (HDMI_RES_GROUP_T)( ((f) >> 16) & 0xff ))
-#define GETFLAGS_MODE(f) ( ( (f) >>24 ) & 0xff )
-
-static void SetResolutionString(RESOLUTION_INFO &res);
-static SDTV_ASPECT_T get_sdtv_aspect_from_display_aspect(float display_aspect);
-
-CRPIUtils::CRPIUtils()
-{
- m_DllBcmHost = new DllBcmHost;
- m_DllBcmHost->Load();
-
- m_dispman_element = DISPMANX_NO_HANDLE;
- m_dispman_display = DISPMANX_NO_HANDLE;
-
- m_height = 1280;
- m_width = 720;
- m_screen_width = 1280;
- m_screen_height = 720;
- m_shown = false;
-
- m_initDesktopRes = true;
-}
-
-CRPIUtils::~CRPIUtils()
-{
- if(m_DllBcmHost && m_DllBcmHost->IsLoaded())
- {
- m_DllBcmHost->Unload();
- }
-
- delete m_DllBcmHost;
- m_DllBcmHost = NULL;
-}
-
-bool CRPIUtils::GetNativeResolution(RESOLUTION_INFO *res) const
-{
- *res = m_desktopRes;
-
- return true;
-}
-
-int CRPIUtils::FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector<RESOLUTION_INFO> &resolutions, bool desktop)
-{
- uint32_t mask = desktop ? D3DPRESENTFLAG_MODEMASK : D3DPRESENTFLAG_MODE3DSBS|D3DPRESENTFLAG_MODE3DTB;
- for (int i = 0; i < (int)resolutions.size(); i++)
- {
- if(resolutions[i].iScreenWidth == res.iScreenWidth && resolutions[i].iScreenHeight == res.iScreenHeight && resolutions[i].fRefreshRate == res.fRefreshRate &&
- (resolutions[i].dwFlags & mask) == (res.dwFlags & mask))
- {
- return i;
- }
- }
- return -1;
-}
-
-int CRPIUtils::AddUniqueResolution(RESOLUTION_INFO &res, std::vector<RESOLUTION_INFO> &resolutions, bool desktop /* = false */)
-{
- SetResolutionString(res);
- int i = FindMatchingResolution(res, resolutions, desktop);
- if (i>=0)
- { // don't replace a progressive resolution with an interlaced one of same resolution
- if (!(res.dwFlags & D3DPRESENTFLAG_INTERLACED))
- resolutions[i] = res;
- }
- else
- {
- resolutions.push_back(res);
- }
- return i;
-}
-
-bool CRPIUtils::SetNativeResolution(const RESOLUTION_INFO res, EGLSurface m_nativeWindow)
-{
- if(!m_DllBcmHost || !m_nativeWindow)
- return false;
-
- DestroyDispmanxWindow();
-
- RENDER_STEREO_MODE stereo_mode = CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode();
- if(GETFLAGS_GROUP(res.dwFlags) && GETFLAGS_MODE(res.dwFlags))
- {
- uint32_t mode3d = HDMI_3D_FORMAT_NONE;
- sem_init(&m_tv_synced, 0, 0);
- m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this);
-
- if (stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL || stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
- {
- /* inform TV of any 3D settings. Note this property just applies to next hdmi mode change, so no need to call for 2D modes */
- HDMI_PROPERTY_PARAM_T property;
- property.property = HDMI_PROPERTY_3D_STRUCTURE;
- const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
- if (settings->GetBool(CSettings::SETTING_VIDEOSCREEN_FRAMEPACKING) &&
- settings->GetBool(CSettings::SETTING_VIDEOPLAYER_SUPPORTMVC) && res.fRefreshRate <= 30.0f)
- property.param1 = HDMI_3D_FORMAT_FRAME_PACKING;
- else if (stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
- property.param1 = HDMI_3D_FORMAT_SBS_HALF;
- else if (stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
- property.param1 = HDMI_3D_FORMAT_TB_HALF;
- else
- property.param1 = HDMI_3D_FORMAT_NONE;
- property.param2 = 0;
- mode3d = property.param1;
- vc_tv_hdmi_set_property(&property);
- }
-
- HDMI_PROPERTY_PARAM_T property;
- property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE;
- // if we are closer to ntsc version of framerate, let gpu know
- int iFrameRate = (int)(res.fRefreshRate + 0.5f);
- if (fabsf(res.fRefreshRate * (1001.0f / 1000.0f) - iFrameRate) < fabsf(res.fRefreshRate - iFrameRate))
- property.param1 = HDMI_PIXEL_CLOCK_TYPE_NTSC;
- else
- property.param1 = HDMI_PIXEL_CLOCK_TYPE_PAL;
- property.param2 = 0;
- vc_tv_hdmi_set_property(&property);
-
- int success = m_DllBcmHost->vc_tv_hdmi_power_on_explicit_new(HDMI_MODE_HDMI, GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags));
-
- if (success == 0)
- {
- CLog::Log(LOGDEBUG, "EGL set HDMI mode (%d,%d)=%d %s%s", GETFLAGS_GROUP(res.dwFlags),
- GETFLAGS_MODE(res.dwFlags), success,
- CStereoscopicsManager::ConvertGuiStereoModeToString(stereo_mode),
- mode3d == HDMI_3D_FORMAT_FRAME_PACKING
- ? " FP"
- : mode3d == HDMI_3D_FORMAT_SBS_HALF
- ? " SBS"
- : mode3d == HDMI_3D_FORMAT_TB_HALF ? " TB" : "");
-
- sem_wait(&m_tv_synced);
- }
- else
- {
- CLog::Log(LOGERROR, "EGL failed to set HDMI mode (%d,%d)=%d %s%s",
- GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success,
- CStereoscopicsManager::ConvertGuiStereoModeToString(stereo_mode),
- mode3d == HDMI_3D_FORMAT_FRAME_PACKING
- ? " FP"
- : mode3d == HDMI_3D_FORMAT_SBS_HALF
- ? " SBS"
- : mode3d == HDMI_3D_FORMAT_TB_HALF ? " TB" : "");
- }
- m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback);
- sem_destroy(&m_tv_synced);
-
- m_desktopRes = res;
- }
- else if(!GETFLAGS_GROUP(res.dwFlags) && GETFLAGS_MODE(res.dwFlags))
- {
- sem_init(&m_tv_synced, 0, 0);
- m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this);
-
- SDTV_OPTIONS_T options;
- options.aspect = get_sdtv_aspect_from_display_aspect((float)res.iScreenWidth / (float)res.iScreenHeight);
-
- int success = m_DllBcmHost->vc_tv_sdtv_power_on((SDTV_MODE_T)GETFLAGS_MODE(res.dwFlags), &options);
-
- if (success == 0)
- {
- CLog::Log(LOGDEBUG, "EGL set SDTV mode (%d,%d)=%d", GETFLAGS_GROUP(res.dwFlags),
- GETFLAGS_MODE(res.dwFlags), success);
-
- sem_wait(&m_tv_synced);
- }
- else
- {
- CLog::Log(LOGERROR, "EGL failed to set SDTV mode (%d,%d)=%d", GETFLAGS_GROUP(res.dwFlags),
- GETFLAGS_MODE(res.dwFlags), success);
- }
- m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback);
- sem_destroy(&m_tv_synced);
-
- m_desktopRes = res;
- }
-
- m_dispman_display = g_RBP.OpenDisplay(0);
-
- m_width = res.iWidth;
- m_height = res.iHeight;
-
- m_screen_width = res.iScreenWidth;
- m_screen_height = res.iScreenHeight;
-
- VC_RECT_T dst_rect;
- VC_RECT_T src_rect;
-
- dst_rect.x = 0;
- dst_rect.y = 0;
- dst_rect.width = m_screen_width;
- dst_rect.height = m_screen_height;
-
- src_rect.x = 0;
- src_rect.y = 0;
- src_rect.width = m_width << 16;
- src_rect.height = m_height << 16;
-
- VC_DISPMANX_ALPHA_T alpha;
- memset(&alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T));
- alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;
-
- DISPMANX_CLAMP_T clamp;
- memset(&clamp, 0x0, sizeof(DISPMANX_CLAMP_T));
-
- DISPMANX_TRANSFORM_T transform = DISPMANX_NO_ROTATE;
- DISPMANX_UPDATE_HANDLE_T dispman_update = m_DllBcmHost->vc_dispmanx_update_start(0);
-
- if (stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
- transform = DISPMANX_STEREOSCOPIC_SBS;
- else if (stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
- transform = DISPMANX_STEREOSCOPIC_TB;
- else
- transform = DISPMANX_STEREOSCOPIC_MONO;
-
- CLog::Log(LOGDEBUG, "EGL set resolution %dx%d -> %dx%d @ %.2f fps (%d,%d) flags:%x aspect:%.2f",
- m_width, m_height, dst_rect.width, dst_rect.height, res.fRefreshRate,
- GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), (int)res.dwFlags,
- res.fPixelRatio);
-
- m_dispman_element = m_DllBcmHost->vc_dispmanx_element_add(dispman_update,
- m_dispman_display,
- 1, // layer
- &dst_rect,
- (DISPMANX_RESOURCE_HANDLE_T)0, // src
- &src_rect,
- DISPMANX_PROTECTION_NONE,
- &alpha, //alpha
- &clamp, //clamp
- transform); // transform
-
- assert(m_dispman_element != DISPMANX_NO_HANDLE);
- assert(m_dispman_element != (unsigned)DISPMANX_INVALID);
-
- memset(m_nativeWindow, 0, sizeof(EGL_DISPMANX_WINDOW_T));
-
- EGL_DISPMANX_WINDOW_T *nativeWindow = (EGL_DISPMANX_WINDOW_T *)m_nativeWindow;
-
- nativeWindow->element = m_dispman_element;
- nativeWindow->width = m_width;
- nativeWindow->height = m_height;
-
- m_DllBcmHost->vc_dispmanx_display_set_background(dispman_update, m_dispman_display, 0x00, 0x00, 0x00);
- m_DllBcmHost->vc_dispmanx_update_submit_sync(dispman_update);
- m_shown = true;
-
- return true;
-}
-
-static float get_display_aspect_ratio(HDMI_ASPECT_T aspect)
-{
- float display_aspect;
- switch (aspect) {
- case HDMI_ASPECT_4_3: display_aspect = 4.0/3.0; break;
- case HDMI_ASPECT_14_9: display_aspect = 14.0/9.0; break;
- case HDMI_ASPECT_16_9: display_aspect = 16.0/9.0; break;
- case HDMI_ASPECT_5_4: display_aspect = 5.0/4.0; break;
- case HDMI_ASPECT_16_10: display_aspect = 16.0/10.0; break;
- case HDMI_ASPECT_15_9: display_aspect = 15.0/9.0; break;
- case HDMI_ASPECT_64_27: display_aspect = 64.0/27.0; break;
- default: display_aspect = 16.0/9.0; break;
- }
- return display_aspect;
-}
-
-static float get_display_aspect_ratio(SDTV_ASPECT_T aspect)
-{
- float display_aspect;
- switch (aspect) {
- case SDTV_ASPECT_4_3: display_aspect = 4.0/3.0; break;
- case SDTV_ASPECT_14_9: display_aspect = 14.0/9.0; break;
- case SDTV_ASPECT_16_9: display_aspect = 16.0/9.0; break;
- default: display_aspect = 4.0/3.0; break;
- }
- return display_aspect;
-}
-
-static bool ClampToGUIDisplayLimits(int &width, int &height)
-{
- float max_height = (float)g_RBP.GetGUIResolutionLimit();
- float default_ar = 16.0f/9.0f;
- if (max_height < 540.0f || max_height > 1080.0f)
- max_height = 1080.0f;
-
- float ar = (float)width/(float)height;
- float max_width = max_height * default_ar;
- // bigger than maximum, so need to clamp
- if (width > max_width || height > max_height) {
- // wider than max, so clamp width first
- if (ar > default_ar)
- {
- width = max_width;
- height = max_width / ar + 0.5f;
- // taller than max, so clamp height first
- } else {
- height = max_height;
- width = max_height * ar + 0.5f;
- }
- return true;
- }
-
- return false;
-}
-
-static void SetResolutionString(RESOLUTION_INFO &res)
-{
- int gui_width = res.iScreenWidth;
- int gui_height = res.iScreenHeight;
-
- ClampToGUIDisplayLimits(gui_width, gui_height);
-
- res.iWidth = gui_width;
- res.iHeight = gui_height;
-
- res.strMode = StringUtils::Format("%dx%d (%dx%d) @ %.2f%s - Full Screen", res.iScreenWidth, res.iScreenHeight, res.iWidth, res.iHeight, res.fRefreshRate,
- res.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
-}
-
-static SDTV_ASPECT_T get_sdtv_aspect_from_display_aspect(float display_aspect)
-{
- SDTV_ASPECT_T aspect;
- const float delta = 1e-3;
- if(fabs(get_display_aspect_ratio(SDTV_ASPECT_16_9) - display_aspect) < delta)
- {
- aspect = SDTV_ASPECT_16_9;
- }
- else if(fabs(get_display_aspect_ratio(SDTV_ASPECT_14_9) - display_aspect) < delta)
- {
- aspect = SDTV_ASPECT_14_9;
- }
- else
- {
- aspect = SDTV_ASPECT_4_3;
- }
- return aspect;
-}
-
-bool CRPIUtils::ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions)
-{
- resolutions.clear();
-
- if(!m_DllBcmHost)
- return false;
-
- /* read initial desktop resolution before probe resolutions.
- * probing will replace the desktop resolution when it finds the same one.
- * we replace it because probing will generate more detailed
- * resolution flags we don't get with vc_tv_get_state.
- */
-
- if(m_initDesktopRes)
- {
- TV_DISPLAY_STATE_T tv_state;
-
- // get current display settings state
- memset(&tv_state, 0, sizeof(TV_DISPLAY_STATE_T));
- m_DllBcmHost->vc_tv_get_display_state(&tv_state);
-
- if ((tv_state.state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) != 0) // hdtv
- {
- m_desktopRes.bFullScreen = true;
- m_desktopRes.iWidth = tv_state.display.hdmi.width;
- m_desktopRes.iHeight = tv_state.display.hdmi.height;
- m_desktopRes.iScreenWidth = tv_state.display.hdmi.width;
- m_desktopRes.iScreenHeight= tv_state.display.hdmi.height;
- m_desktopRes.dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode);
- m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
- HDMI_PROPERTY_PARAM_T property;
- property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE;
- vc_tv_hdmi_get_property(&property);
- m_desktopRes.fRefreshRate = property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tv_state.display.hdmi.frame_rate * (1000.0f/1001.0f) : tv_state.display.hdmi.frame_rate;
- }
- else if ((tv_state.state & ( VC_SDTV_NTSC | VC_SDTV_PAL )) != 0) // sdtv
- {
- m_desktopRes.bFullScreen = true;
- m_desktopRes.iWidth = tv_state.display.sdtv.width;
- m_desktopRes.iHeight = tv_state.display.sdtv.height;
- m_desktopRes.iScreenWidth = tv_state.display.sdtv.width;
- m_desktopRes.iScreenHeight= tv_state.display.sdtv.height;
- m_desktopRes.dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, tv_state.display.sdtv.mode, 1);
- m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate;
- m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
- }
- else if ((tv_state.state & VC_LCD_ATTACHED_DEFAULT) != 0) // lcd
- {
- m_desktopRes.bFullScreen = true;
- m_desktopRes.iWidth = tv_state.display.sdtv.width;
- m_desktopRes.iHeight = tv_state.display.sdtv.height;
- m_desktopRes.iScreenWidth = tv_state.display.sdtv.width;
- m_desktopRes.iScreenHeight= tv_state.display.sdtv.height;
- m_desktopRes.dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, 0, 0);
- m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate;
- m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
- }
-
- SetResolutionString(m_desktopRes);
-
- m_initDesktopRes = false;
-
- m_desktopRes.iSubtitles = (int)(0.965 * m_desktopRes.iHeight);
-
- CLog::Log(LOGDEBUG, "EGL initial desktop resolution %s (%.2f)", m_desktopRes.strMode.c_str(),
- m_desktopRes.fPixelRatio);
- }
-
- if(GETFLAGS_GROUP(m_desktopRes.dwFlags) && GETFLAGS_MODE(m_desktopRes.dwFlags))
- {
- GetSupportedModes(HDMI_RES_GROUP_DMT, resolutions);
- GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions);
- }
- {
- AddUniqueResolution(m_desktopRes, resolutions, true);
- CLog::Log(LOGDEBUG, "EGL probe resolution %s:%x", m_desktopRes.strMode.c_str(),
- m_desktopRes.dwFlags);
- }
-
- return true;
-}
-
-void CRPIUtils::DestroyDispmanxWindow()
-{
- if(!m_DllBcmHost)
- return;
-
- DISPMANX_UPDATE_HANDLE_T dispman_update = m_DllBcmHost->vc_dispmanx_update_start(0);
-
- if (m_dispman_element != DISPMANX_NO_HANDLE)
- {
- m_DllBcmHost->vc_dispmanx_element_remove(dispman_update, m_dispman_element);
- m_dispman_element = DISPMANX_NO_HANDLE;
- }
- m_DllBcmHost->vc_dispmanx_update_submit_sync(dispman_update);
-
- if (m_dispman_display != DISPMANX_NO_HANDLE)
- {
- g_RBP.CloseDisplay(m_dispman_display);
- m_dispman_display = DISPMANX_NO_HANDLE;
- }
-}
-
-void CRPIUtils::SetVisible(bool enable)
-{
- if(!m_DllBcmHost || m_shown == enable)
- return;
-
- CLog::Log(LOGDEBUG, "CRPIUtils::EnableDispmanxWindow(%d)", enable);
-
- DISPMANX_UPDATE_HANDLE_T dispman_update = m_DllBcmHost->vc_dispmanx_update_start(0);
-
- if (m_dispman_element != DISPMANX_NO_HANDLE)
- {
- VC_RECT_T dst_rect;
- if (enable)
- {
- dst_rect.x = 0;
- dst_rect.y = 0;
- dst_rect.width = m_screen_width;
- dst_rect.height = m_screen_height;
- }
- else
- {
- dst_rect.x = m_screen_width;
- dst_rect.y = m_screen_height;
- dst_rect.width = m_screen_width;
- dst_rect.height = m_screen_height;
- }
- m_shown = enable;
- m_DllBcmHost->vc_dispmanx_element_change_attributes(dispman_update, m_dispman_element,
- (1<<2), 0, 0, &dst_rect, nullptr, 0, DISPMANX_NO_ROTATE);
- }
- m_DllBcmHost->vc_dispmanx_update_submit(dispman_update, nullptr, nullptr);
-}
-
-void CRPIUtils::GetSupportedModes(HDMI_RES_GROUP_T group, std::vector<RESOLUTION_INFO> &resolutions)
-{
- if(!m_DllBcmHost)
- return;
-
- //Supported HDMI CEA/DMT resolutions, preferred resolution will be returned
- int32_t num_modes = 0;
- HDMI_RES_GROUP_T prefer_group;
- uint32_t prefer_mode;
- int i;
- TV_SUPPORTED_MODE_NEW_T *supported_modes = NULL;
- // query the number of modes first
- int max_supported_modes = m_DllBcmHost->vc_tv_hdmi_get_supported_modes_new(group, NULL, 0, &prefer_group, &prefer_mode);
-
- if (max_supported_modes > 0)
- supported_modes = new TV_SUPPORTED_MODE_NEW_T[max_supported_modes];
-
- if (supported_modes)
- {
- num_modes = m_DllBcmHost->vc_tv_hdmi_get_supported_modes_new(group,
- supported_modes, max_supported_modes, &prefer_group, &prefer_mode);
-
- CLog::Log(LOGDEBUG, "EGL get supported modes (%d) = %d, prefer_group=%x, prefer_mode=%x", group,
- num_modes, prefer_group, prefer_mode);
- }
-
- if (num_modes > 0 && prefer_group != HDMI_RES_GROUP_INVALID)
- {
- TV_SUPPORTED_MODE_NEW_T *tv = supported_modes;
- for (i=0; i < num_modes; i++, tv++)
- {
- RESOLUTION_INFO res;
-
- res.bFullScreen = true;
- res.dwFlags = MAKEFLAGS(group, tv->code, tv->scan_mode);
- res.fRefreshRate = (float)tv->frame_rate;
- res.iWidth = tv->width;
- res.iHeight = tv->height;
- res.iScreenWidth = tv->width;
- res.iScreenHeight = tv->height;
- res.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res.iScreenWidth / (float)res.iScreenHeight);
- res.iSubtitles = (int)(0.965 * res.iHeight);
-
- if (!m_desktopRes.dwFlags && prefer_group == group && prefer_mode == tv->code)
- m_desktopRes = res;
-
- AddUniqueResolution(res, resolutions);
- CLog::Log(LOGDEBUG, "EGL mode %d: %s (%.2f) %s%s:%x", i, res.strMode, res.fPixelRatio,
- tv->native ? "N" : "", tv->scan_mode ? "I" : "", int(tv->code));
-
- if (tv->frame_rate == 24 || tv->frame_rate == 30 || tv->frame_rate == 48 || tv->frame_rate == 60 || tv->frame_rate == 72)
- {
- RESOLUTION_INFO res2 = res;
- res2.fRefreshRate = (float)tv->frame_rate * (1000.0f/1001.0f);
- AddUniqueResolution(res2, resolutions);
- }
- }
- }
- if (supported_modes)
- delete [] supported_modes;
-}
-
-void CRPIUtils::TvServiceCallback(uint32_t reason, uint32_t param1, uint32_t param2)
-{
- CLog::Log(LOGDEBUG, "EGL tv_service_callback (%d,%d,%d)", reason, param1, param2);
- switch(reason)
- {
- case VC_HDMI_UNPLUGGED:
- break;
- case VC_HDMI_STANDBY:
- break;
- case VC_SDTV_NTSC:
- case VC_SDTV_PAL:
- case VC_HDMI_HDMI:
- case VC_HDMI_DVI:
- //Signal we are ready now
- sem_post(&m_tv_synced);
- break;
- default:
- break;
- }
-}
-
-void CRPIUtils::CallbackTvServiceCallback(void *userdata, uint32_t reason, uint32_t param1, uint32_t param2)
-{
- CRPIUtils *callback = static_cast<CRPIUtils*>(userdata);
- callback->TvServiceCallback(reason, param1, param2);
-}
diff --git a/xbmc/windowing/rpi/RPIUtils.h b/xbmc/windowing/rpi/RPIUtils.h
deleted file mode 100644
index a90c22397c..0000000000
--- a/xbmc/windowing/rpi/RPIUtils.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 "windowing/Resolution.h"
-
-#include "platform/linux/RBP.h"
-
-#include <EGL/egl.h>
-#include <bcm_host.h>
-
-class DllBcmHost;
-class CRPIUtils
-{
-public:
- CRPIUtils();
- virtual ~CRPIUtils();
- virtual void DestroyDispmanxWindow();
- virtual void SetVisible(bool enable);
- virtual bool GetNativeResolution(RESOLUTION_INFO *res) const;
- virtual bool SetNativeResolution(const RESOLUTION_INFO res, EGLSurface m_nativeWindow);
- virtual bool ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions);
-private:
- DllBcmHost *m_DllBcmHost;
- DISPMANX_ELEMENT_HANDLE_T m_dispman_display;
- DISPMANX_ELEMENT_HANDLE_T m_dispman_element;
- TV_GET_STATE_RESP_T m_tv_state;
- sem_t m_tv_synced;
- RESOLUTION_INFO m_desktopRes;
- int m_width;
- int m_height;
- int m_screen_width;
- int m_screen_height;
- bool m_shown;
-
- int m_initDesktopRes;
-
- void GetSupportedModes(HDMI_RES_GROUP_T group, std::vector<RESOLUTION_INFO> &resolutions);
- void TvServiceCallback(uint32_t reason, uint32_t param1, uint32_t param2);
- static void CallbackTvServiceCallback(void *userdata, uint32_t reason, uint32_t param1, uint32_t param2);
-
- int FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector<RESOLUTION_INFO> &resolutions, bool desktop);
- int AddUniqueResolution(RESOLUTION_INFO &res, std::vector<RESOLUTION_INFO> &resolutions, bool desktop = false);
-};
diff --git a/xbmc/windowing/rpi/VideoSyncPi.cpp b/xbmc/windowing/rpi/VideoSyncPi.cpp
deleted file mode 100644
index 04f095d284..0000000000
--- a/xbmc/windowing/rpi/VideoSyncPi.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2005-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "VideoSyncPi.h"
-
-#include "ServiceBroker.h"
-#include "threads/Thread.h"
-#include "utils/TimeUtils.h"
-#include "utils/log.h"
-#include "windowing/GraphicContext.h"
-#include "windowing/WinSystem.h"
-
-#include "platform/linux/RBP.h"
-
-bool CVideoSyncPi::Setup(PUPDATECLOCK func)
-{
- UpdateClock = func;
- m_abort = false;
- CServiceBroker::GetWinSystem()->Register(this);
- CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up RPi");
- return true;
-}
-
-void CVideoSyncPi::Run(CEvent& stopEvent)
-{
- CThread* thread = CThread::GetCurrentThread();
- if (thread != nullptr)
- {
- /* This shouldn't be very busy and timing is important so increase priority */
- thread->SetPriority(thread->GetPriority() + 1);
- }
-
- while (!stopEvent.Signaled() && !m_abort)
- {
- g_RBP.WaitVsync();
- uint64_t now = CurrentHostCounter();
- UpdateClock(1, now, m_refClock);
- }
-}
-
-void CVideoSyncPi::Cleanup()
-{
- CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up RPi");
- CServiceBroker::GetWinSystem()->Unregister(this);
-}
-
-float CVideoSyncPi::GetFps()
-{
- m_fps = CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS();
- CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.2f", m_fps);
- return m_fps;
-}
-
-void CVideoSyncPi::OnResetDisplay()
-{
- m_abort = true;
-}
-
-void CVideoSyncPi::RefreshChanged()
-{
- if (m_fps != CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS())
- m_abort = true;
-}
diff --git a/xbmc/windowing/rpi/VideoSyncPi.h b/xbmc/windowing/rpi/VideoSyncPi.h
deleted file mode 100644
index b1c41e85b9..0000000000
--- a/xbmc/windowing/rpi/VideoSyncPi.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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 "guilib/DispResource.h"
-#include "windowing/VideoSync.h"
-
-class CVideoSyncPi : public CVideoSync, IDispResource
-{
-public:
- CVideoSyncPi(void *clock) : CVideoSync(clock) {};
- virtual bool Setup(PUPDATECLOCK func);
- virtual void Run(CEvent& stopEvent);
- virtual void Cleanup();
- virtual float GetFps();
- virtual void OnResetDisplay();
- virtual void RefreshChanged();
-
-private:
- volatile bool m_abort;
-};
diff --git a/xbmc/windowing/rpi/WinSystemRpi.cpp b/xbmc/windowing/rpi/WinSystemRpi.cpp
deleted file mode 100644
index ed506d6dfe..0000000000
--- a/xbmc/windowing/rpi/WinSystemRpi.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2005-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "WinSystemRpi.h"
-
-#include "ServiceBroker.h"
-#include "cores/AudioEngine/AESinkFactory.h"
-#include "cores/AudioEngine/Sinks/AESinkPi.h"
-#include "guilib/DispResource.h"
-#include "settings/DisplaySettings.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "utils/log.h"
-#include "windowing/GraphicContext.h"
-#include "windowing/Resolution.h"
-
-#include "platform/linux/DllBCM.h"
-#include "platform/linux/RBP.h"
-#include "platform/linux/powermanagement/LinuxPowerSyscall.h"
-
-#include <float.h>
-#include <string.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglplatform.h>
-
-CWinSystemRpi::CWinSystemRpi() :
- m_libinput(new CLibInputHandler)
-{
- m_nativeDisplay = EGL_NO_DISPLAY;
- m_nativeWindow = EGL_NO_SURFACE;
-
- m_displayWidth = 0;
- m_displayHeight = 0;
-
- m_stereo_mode = RENDER_STEREO_MODE_OFF;
- m_delayDispReset = false;
-
- m_rpi = new CRPIUtils();
-
- AE::CAESinkFactory::ClearSinks();
-
- CAESinkPi::Register();
- std::string envSink;
- if (getenv("KODI_AE_SINK"))
- envSink = getenv("KODI_AE_SINK");
-
- if (StringUtils::EqualsNoCase(envSink, "PULSE"))
- {
- OPTIONALS::PulseAudioRegister();
- }
- else if (StringUtils::EqualsNoCase(envSink, "ALSA+PULSE"))
- {
- OPTIONALS::ALSARegister();
- OPTIONALS::PulseAudioRegister();
- }
- else
- {
- OPTIONALS::ALSARegister();
- }
-
- CLinuxPowerSyscall::Register();
- m_lirc.reset(OPTIONALS::LircRegister());
- m_libinput->Start();
-}
-
-CWinSystemRpi::~CWinSystemRpi()
-{
- if(m_nativeWindow)
- {
- m_nativeWindow = nullptr;
- }
-
- delete m_rpi;
- m_rpi = nullptr;
-}
-
-bool CWinSystemRpi::InitWindowSystem()
-{
- m_nativeDisplay = EGL_DEFAULT_DISPLAY;
-
- return CWinSystemBase::InitWindowSystem();
-}
-
-bool CWinSystemRpi::DestroyWindowSystem()
-{
- return true;
-}
-
-bool CWinSystemRpi::CreateNewWindow(const std::string& name,
- bool fullScreen,
- RESOLUTION_INFO& res)
-{
- RESOLUTION_INFO current_resolution;
- current_resolution.iWidth = current_resolution.iHeight = 0;
- RENDER_STEREO_MODE stereo_mode = CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode();
-
- m_nWidth = res.iWidth;
- m_nHeight = res.iHeight;
- m_displayWidth = res.iScreenWidth;
- m_displayHeight = res.iScreenHeight;
- m_fRefreshRate = res.fRefreshRate;
-
- if ((m_bWindowCreated && m_rpi->GetNativeResolution(&current_resolution)) &&
- current_resolution.iWidth == res.iWidth && current_resolution.iHeight == res.iHeight &&
- current_resolution.iScreenWidth == res.iScreenWidth && current_resolution.iScreenHeight == res.iScreenHeight &&
- m_bFullScreen == fullScreen && current_resolution.fRefreshRate == res.fRefreshRate &&
- (current_resolution.dwFlags & D3DPRESENTFLAG_MODEMASK) == (res.dwFlags & D3DPRESENTFLAG_MODEMASK) &&
- m_stereo_mode == stereo_mode)
- {
- CLog::Log(LOGDEBUG, "CWinSystemEGL::CreateNewWindow: No need to create a new window");
- return true;
- }
-
- int delay = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt("videoscreen.delayrefreshchange");
- if (delay > 0)
- {
- m_delayDispReset = true;
- m_dispResetTimer.Set(delay * 100);
- }
-
- {
- CSingleLock lock(m_resourceSection);
- for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
- {
- (*i)->OnLostDisplay();
- }
- }
-
- m_stereo_mode = stereo_mode;
- m_bFullScreen = fullScreen;
-
- m_nativeWindow = static_cast<EGLNativeWindowType>(new EGL_DISPMANX_WINDOW_T);
-
- m_rpi->SetNativeResolution(res, m_nativeWindow);
-
- if (!m_delayDispReset)
- {
- CSingleLock lock(m_resourceSection);
- // tell any shared resources
- for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
- {
- (*i)->OnResetDisplay();
- }
- }
-
- return true;
-}
-
-bool CWinSystemRpi::DestroyWindow()
-{
- m_rpi->DestroyDispmanxWindow();
- m_nativeWindow = nullptr;
-
- return true;
-}
-
-void CWinSystemRpi::UpdateResolutions()
-{
- CWinSystemBase::UpdateResolutions();
-
- RESOLUTION_INFO resDesktop, curDisplay;
- std::vector<RESOLUTION_INFO> resolutions;
-
- if (!m_rpi->ProbeResolutions(resolutions) || resolutions.empty())
- {
- CLog::Log(LOGWARNING, "%s: ProbeResolutions failed.",__FUNCTION__);
- }
-
- /* ProbeResolutions includes already all resolutions.
- * Only get desktop resolution so we can replace xbmc's desktop res
- */
- if (m_rpi->GetNativeResolution(&curDisplay))
- {
- resDesktop = curDisplay;
- }
-
- RESOLUTION ResDesktop = RES_INVALID;
- RESOLUTION res_index = RES_DESKTOP;
-
- for (size_t i = 0; i < resolutions.size(); i++)
- {
- // if this is a new setting,
- // create a new empty setting to fill in.
- if ((int)CDisplaySettings::GetInstance().ResolutionInfoSize() <= res_index)
- {
- RESOLUTION_INFO res;
- CDisplaySettings::GetInstance().AddResolutionInfo(res);
- }
-
- CServiceBroker::GetWinSystem()->GetGfxContext().ResetOverscan(resolutions[i]);
- CDisplaySettings::GetInstance().GetResolutionInfo(res_index) = resolutions[i];
-
- CLog::Log(LOGINFO, "Found resolution %d x %d with %d x %d%s @ %f Hz", resolutions[i].iWidth,
- resolutions[i].iHeight, resolutions[i].iScreenWidth, resolutions[i].iScreenHeight,
- resolutions[i].dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "",
- resolutions[i].fRefreshRate);
-
- if(resDesktop.iWidth == resolutions[i].iWidth &&
- resDesktop.iHeight == resolutions[i].iHeight &&
- resDesktop.iScreenWidth == resolutions[i].iScreenWidth &&
- resDesktop.iScreenHeight == resolutions[i].iScreenHeight &&
- (resDesktop.dwFlags & D3DPRESENTFLAG_MODEMASK) == (resolutions[i].dwFlags & D3DPRESENTFLAG_MODEMASK) &&
- fabs(resDesktop.fRefreshRate - resolutions[i].fRefreshRate) < FLT_EPSILON)
- {
- ResDesktop = res_index;
- }
-
- res_index = (RESOLUTION)((int)res_index + 1);
- }
-
- // set RES_DESKTOP
- if (ResDesktop != RES_INVALID)
- {
- CLog::Log(LOGINFO, "Found (%dx%d%s@%f) at %d, setting to RES_DESKTOP at %d", resDesktop.iWidth,
- resDesktop.iHeight, resDesktop.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "",
- resDesktop.fRefreshRate, (int)ResDesktop, (int)RES_DESKTOP);
-
- CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP) = CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop);
- }
-}
-
-bool CWinSystemRpi::Hide()
-{
- return false;
-}
-
-bool CWinSystemRpi::Show(bool raise)
-{
- return true;
-}
-
-void CWinSystemRpi::SetVisible(bool visible)
-{
- m_rpi->SetVisible(visible);
-}
-
-void CWinSystemRpi::Register(IDispResource *resource)
-{
- CSingleLock lock(m_resourceSection);
- m_resources.push_back(resource);
-}
-
-void CWinSystemRpi::Unregister(IDispResource *resource)
-{
- CSingleLock lock(m_resourceSection);
- std::vector<IDispResource*>::iterator i = find(m_resources.begin(), m_resources.end(), resource);
- if (i != m_resources.end())
- m_resources.erase(i);
-}
diff --git a/xbmc/windowing/rpi/WinSystemRpi.h b/xbmc/windowing/rpi/WinSystemRpi.h
deleted file mode 100644
index 3c6f6e7477..0000000000
--- a/xbmc/windowing/rpi/WinSystemRpi.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 "RPIUtils.h"
-#include "rendering/gles/RenderSystemGLES.h"
-#include "threads/CriticalSection.h"
-#include "threads/SystemClock.h"
-#include "windowing/WinSystem.h"
-
-#include "platform/freebsd/OptionalsReg.h"
-#include "platform/linux/OptionalsReg.h"
-#include "platform/linux/input/LibInputHandler.h"
-
-#include <EGL/egl.h>
-
-class IDispResource;
-
-class CWinSystemRpi : public CWinSystemBase
-{
-public:
- CWinSystemRpi();
- virtual ~CWinSystemRpi();
-
- bool InitWindowSystem() override;
- bool DestroyWindowSystem() override;
-
- bool CreateNewWindow(const std::string& name,
- bool fullScreen,
- RESOLUTION_INFO& res) override;
-
- bool DestroyWindow() override;
- void UpdateResolutions() override;
-
- bool Hide() override;
- bool Show(bool raise = true) override;
- void SetVisible(bool visible);
- virtual void Register(IDispResource *resource);
- virtual void Unregister(IDispResource *resource);
-protected:
- CRPIUtils *m_rpi;
- EGLDisplay m_nativeDisplay;
- EGLSurface m_nativeWindow;
-
- int m_displayWidth;
- int m_displayHeight;
-
- RENDER_STEREO_MODE m_stereo_mode;
-
- bool m_delayDispReset;
- XbmcThreads::EndTime m_dispResetTimer;
-
- CCriticalSection m_resourceSection;
- std::vector<IDispResource*> m_resources;
- std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc;
- std::unique_ptr<CLibInputHandler> m_libinput;
-};
diff --git a/xbmc/windowing/rpi/WinSystemRpiGLESContext.cpp b/xbmc/windowing/rpi/WinSystemRpiGLESContext.cpp
deleted file mode 100644
index 7a3c7ee25a..0000000000
--- a/xbmc/windowing/rpi/WinSystemRpiGLESContext.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2005-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#include "WinSystemRpiGLESContext.h"
-
-#include "Application.h"
-#include "ServiceBroker.h"
-#include "VideoSyncPi.h"
-#include "cores/RetroPlayer/process/rbpi/RPProcessInfoPi.h"
-#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
-#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
-#include "cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h"
-#include "cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h"
-#include "cores/VideoPlayer/Process/rbpi/ProcessInfoPi.h"
-#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
-#include "guilib/GUIComponent.h"
-#include "guilib/GUIWindowManager.h"
-#include "rendering/gles/ScreenshotSurfaceGLES.h"
-#include "utils/log.h"
-
-#include "platform/linux/ScreenshotSurfaceRBP.h"
-
-using namespace KODI;
-
-
-std::unique_ptr<CWinSystemBase> CWinSystemBase::CreateWinSystem()
-{
- std::unique_ptr<CWinSystemBase> winSystem(new CWinSystemRpiGLESContext());
- return winSystem;
-}
-
-bool CWinSystemRpiGLESContext::InitWindowSystem()
-{
- if (!CWinSystemRpi::InitWindowSystem())
- {
- return false;
- }
-
- if (!m_pGLContext.CreateDisplay(m_nativeDisplay))
- {
- return false;
- }
-
- if (!m_pGLContext.InitializeDisplay(EGL_OPENGL_ES_API))
- {
- return false;
- }
-
- if (!m_pGLContext.ChooseConfig(EGL_OPENGL_ES2_BIT))
- {
- return false;
- }
-
- CEGLAttributesVec contextAttribs;
- contextAttribs.Add({{EGL_CONTEXT_CLIENT_VERSION, 2}});
-
- if (!m_pGLContext.CreateContext(contextAttribs))
- {
- return false;
- }
-
- CProcessInfoPi::Register();
- RETRO::CRPProcessInfoPi::Register();
- RETRO::CRPProcessInfoPi::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES);
- CDVDFactoryCodec::ClearHWAccels();
- MMAL::CDecoder::Register();
- CDVDFactoryCodec::ClearHWVideoCodecs();
- MMAL::CMMALVideo::Register();
- VIDEOPLAYER::CRendererFactory::ClearRenderer();
- MMAL::CMMALRenderer::Register();
- CScreenshotSurfaceGLES::Register();
- CScreenshotSurfaceRBP::Register();
-
- return true;
-}
-
-bool CWinSystemRpiGLESContext::CreateNewWindow(const std::string& name,
- bool fullScreen,
- RESOLUTION_INFO& res)
-{
- m_pGLContext.DestroySurface();
-
- if (!CWinSystemRpi::DestroyWindow())
- {
- return false;
- }
-
- if (!CWinSystemRpi::CreateNewWindow(name, fullScreen, res))
- {
- return false;
- }
-
- if (!m_pGLContext.CreateSurface(m_nativeWindow))
- {
- return false;
- }
-
- if (!m_pGLContext.BindContext())
- {
- return false;
- }
-
- if (!m_delayDispReset)
- {
- CSingleLock lock(m_resourceSection);
- // tell any shared resources
- for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
- (*i)->OnResetDisplay();
- }
-
- return true;
-}
-
-bool CWinSystemRpiGLESContext::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
-{
- CRenderSystemGLES::ResetRenderSystem(newWidth, newHeight);
- return true;
-}
-
-bool CWinSystemRpiGLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
-{
- CreateNewWindow("", fullScreen, res);
- CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight);
- return true;
-}
-
-void CWinSystemRpiGLESContext::SetVSyncImpl(bool enable)
-{
- if (!m_pGLContext.SetVSync(enable))
- {
- CLog::Log(LOGERROR, "%s,Could not set egl vsync", __FUNCTION__);
- }
-}
-
-void CWinSystemRpiGLESContext::PresentRenderImpl(bool rendered)
-{
- CGUIComponent *gui = CServiceBroker::GetGUI();
- if (gui)
- CWinSystemRpi::SetVisible(gui->GetWindowManager().HasVisibleControls() || g_application.GetAppPlayer().IsRenderingGuiLayer());
-
- if (m_delayDispReset && m_dispResetTimer.IsTimePast())
- {
- m_delayDispReset = false;
- CSingleLock lock(m_resourceSection);
- // tell any shared resources
- for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
- (*i)->OnResetDisplay();
- }
- if (!rendered)
- return;
-
- if (!m_pGLContext.TrySwapBuffers())
- {
- CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
- throw std::runtime_error("eglSwapBuffers failed");
- }
-}
-
-EGLDisplay CWinSystemRpiGLESContext::GetEGLDisplay() const
-{
- return m_pGLContext.GetEGLDisplay();
-}
-
-EGLSurface CWinSystemRpiGLESContext::GetEGLSurface() const
-{
- return m_pGLContext.GetEGLSurface();
-}
-
-EGLContext CWinSystemRpiGLESContext::GetEGLContext() const
-{
- return m_pGLContext.GetEGLContext();
-}
-
-EGLConfig CWinSystemRpiGLESContext::GetEGLConfig() const
-{
- return m_pGLContext.GetEGLConfig();
-}
-
-std::unique_ptr<CVideoSync> CWinSystemRpiGLESContext::GetVideoSync(void *clock)
-{
- std::unique_ptr<CVideoSync> pVSync(new CVideoSyncPi(clock));
- return pVSync;
-}
-
diff --git a/xbmc/windowing/rpi/WinSystemRpiGLESContext.h b/xbmc/windowing/rpi/WinSystemRpiGLESContext.h
deleted file mode 100644
index 0e8ef22a87..0000000000
--- a/xbmc/windowing/rpi/WinSystemRpiGLESContext.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 "WinSystemRpi.h"
-#include "rendering/gles/RenderSystemGLES.h"
-#include "utils/EGLUtils.h"
-
-class CWinSystemRpiGLESContext : public CWinSystemRpi, public CRenderSystemGLES
-{
-public:
- CWinSystemRpiGLESContext() = default;
- virtual ~CWinSystemRpiGLESContext() = default;
-
- // Implementation of CWinSystemBase via CWinSystemRpi
- CRenderSystemBase *GetRenderSystem() override { return this; }
- bool InitWindowSystem() override;
- bool CreateNewWindow(const std::string& name,
- bool fullScreen,
- RESOLUTION_INFO& res) override;
-
- bool ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) override;
- bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override;
-
- virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override;
-
- EGLDisplay GetEGLDisplay() const;
- EGLSurface GetEGLSurface() const;
- EGLContext GetEGLContext() const;
- EGLConfig GetEGLConfig() const;
-protected:
- void SetVSyncImpl(bool enable) override;
- void PresentRenderImpl(bool rendered) override;
-
-private:
- CEGLContextUtils m_pGLContext;
-
-};
diff --git a/xbmc/windowing/wayland/WinSystemWaylandEGLContextGLES.cpp b/xbmc/windowing/wayland/WinSystemWaylandEGLContextGLES.cpp
index 6d051cc4ed..8523a8b75f 100644
--- a/xbmc/windowing/wayland/WinSystemWaylandEGLContextGLES.cpp
+++ b/xbmc/windowing/wayland/WinSystemWaylandEGLContextGLES.cpp
@@ -12,6 +12,8 @@
#include "cores/RetroPlayer/process/RPProcessInfo.h"
#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.h"
#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
+#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h"
+#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h"
#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
#include "rendering/gles/ScreenshotSurfaceGLES.h"
@@ -39,6 +41,9 @@ bool CWinSystemWaylandEGLContextGLES::InitWindowSystem()
CLinuxRendererGLES::Register();
+ CDVDVideoCodecDRMPRIME::Register();
+ CRendererDRMPRIMEGLES::Register();
+
RETRO::CRPProcessInfo::RegisterRendererFactory(new RETRO::CRendererFactoryDMA);
RETRO::CRPProcessInfo::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES);
diff --git a/xbmc/windows/GUIWindowSystemInfo.cpp b/xbmc/windows/GUIWindowSystemInfo.cpp
index e73004d0bb..2b0c23f12c 100644
--- a/xbmc/windows/GUIWindowSystemInfo.cpp
+++ b/xbmc/windows/GUIWindowSystemInfo.cpp
@@ -156,7 +156,7 @@ void CGUIWindowSystemInfo::FrameMove()
SET_CONTROL_LABEL(i++, "Serial: " + CServiceBroker::GetCPUInfo()->GetCPUSerial());
#endif
SetControlLabel(i++, "%s %s", 22011, SYSTEM_CPU_TEMPERATURE);
-#if (!defined(__arm__) && !defined(__aarch64__)) || defined(TARGET_RASPBERRY_PI)
+#if (!defined(__arm__) && !defined(__aarch64__))
SetControlLabel(i++, "%s %s", 13284, SYSTEM_CPUFREQUENCY);
#endif
#if !(defined(__arm__) && defined(TARGET_LINUX))