├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── ChangeLog.txt ├── LICENSE ├── Makefile.am ├── README.md ├── VS2019 ├── chinachu │ ├── chinachu.vcxproj │ └── chinachu.vcxproj.filters ├── pvr.chinachu.sln └── pvr_client │ ├── pvr_client.rc │ ├── pvr_client.vcxproj │ ├── pvr_client.vcxproj.filters │ └── resource.h ├── bootstrap ├── build.ps1 ├── configure.ac ├── include ├── chinachu │ └── genre.h ├── dlfcn-win32.h ├── kodi │ ├── AddonBase.h │ ├── CMakeLists.txt │ ├── Filesystem.h │ ├── General.h │ ├── NOTE │ ├── Network.h │ ├── StreamCodec.h │ ├── StreamCrypto.h │ ├── addon-instance │ │ ├── AudioDecoder.h │ │ ├── AudioEncoder.h │ │ ├── CMakeLists.txt │ │ ├── ImageDecoder.h │ │ ├── Inputstream.h │ │ ├── Peripheral.h │ │ ├── PeripheralUtils.h │ │ ├── Screensaver.h │ │ ├── VFS.h │ │ ├── VideoCodec.h │ │ └── Visualization.h │ ├── filesystem │ │ └── IFileTypes.h │ ├── gui │ │ ├── CMakeLists.txt │ │ ├── General.h │ │ ├── ListItem.h │ │ ├── Window.h │ │ ├── controls │ │ │ ├── Button.h │ │ │ ├── CMakeLists.txt │ │ │ ├── Edit.h │ │ │ ├── FadeLabel.h │ │ │ ├── Image.h │ │ │ ├── Label.h │ │ │ ├── Progress.h │ │ │ ├── RadioButton.h │ │ │ ├── Rendering.h │ │ │ ├── SettingsSlider.h │ │ │ ├── Slider.h │ │ │ ├── Spin.h │ │ │ └── TextBox.h │ │ ├── definitions.h │ │ └── dialogs │ │ │ ├── CMakeLists.txt │ │ │ ├── ContextMenu.h │ │ │ ├── ExtendedProgress.h │ │ │ ├── FileBrowser.h │ │ │ ├── Keyboard.h │ │ │ ├── Numeric.h │ │ │ ├── OK.h │ │ │ ├── Progress.h │ │ │ ├── Select.h │ │ │ ├── TextViewer.h │ │ │ └── YesNo.h │ ├── kodi_game_dll.h │ ├── kodi_game_types.h │ ├── kodi_vfs_types.h │ ├── libKODI_game.h │ ├── libKODI_guilib.h │ ├── libXBMC_addon.h │ ├── libXBMC_pvr.h │ ├── platform │ │ └── android │ │ │ └── System.h │ ├── tools │ │ ├── CMakeLists.txt │ │ └── DllHelper.h │ ├── versions.h │ ├── xbmc_addon_dll.h │ ├── xbmc_addon_types.h │ ├── xbmc_epg_types.h │ ├── xbmc_pvr_dll.h │ └── xbmc_pvr_types.h └── picojson │ ├── LICENSE │ └── picojson.h ├── jni ├── Android.mk ├── Application.mk └── pack.sh ├── src ├── Makefile.am ├── chinachu │ ├── Makefile.am │ ├── api.cpp │ ├── api.h │ ├── chinachu.h │ ├── recorded.cpp │ ├── recorded.h │ ├── recording.cpp │ ├── recording.h │ ├── reserves.cpp │ ├── reserves.h │ ├── rules.cpp │ ├── rules.h │ ├── schedule.cpp │ └── schedule.h ├── dlfcn-win32 │ └── dlfcn-win32.cpp └── pvr_client │ ├── Makefile.am │ ├── channel.cpp │ ├── demux.cpp │ ├── information.cpp │ ├── initialize.cpp │ ├── live.cpp │ ├── recording.cpp │ ├── stream.cpp │ └── timer.cpp └── template └── pvr.chinachu ├── addon.xml ├── fanart.png ├── icon.png ├── icon@2x.png └── resources ├── language ├── English │ └── strings.po └── Japanese │ └── strings.po └── settings.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | *.rc text 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | os: [ubuntu-latest, windows-latest, macOS-latest] 11 | mobile: [true, false] 12 | exclude: 13 | - os: windows-latest 14 | mobile: true 15 | include: 16 | - mobile: false 17 | platform: desktop 18 | - os: macOS-latest 19 | mobile: true 20 | args: --host=arm-apple-darwin 21 | platform: ios 22 | - os: ubuntu-latest 23 | mobile: true 24 | platform: android 25 | fail-fast: false 26 | steps: 27 | - uses: actions/checkout@v1 28 | # Windows Build 29 | - name: build (windows) 30 | if: matrix.os == 'windows-latest' 31 | run: ./build.ps1 32 | shell: powershell 33 | # Android Build 34 | - name: build (android) 35 | if: matrix.platform == 'android' 36 | run: /usr/local/lib/android/sdk/ndk-bundle/ndk-build APP_ABI=armeabi-v7a 37 | - name: pack (android) 38 | if: matrix.platform == 'android' 39 | run: ./jni/pack.sh APP_ABI=armeabi-v7a 40 | # macOS Prepare 41 | - name: prepare (macos) 42 | if: matrix.os == 'macOS-latest' 43 | run: brew install libtool automake 44 | # Linux/macOS/iOS Build 45 | - name: bootstrap 46 | if: matrix.os != 'windows-latest' && matrix.platform != 'android' 47 | run: ./bootstrap 48 | - name: configure 49 | if: matrix.os != 'windows-latest' && matrix.platform != 'android' 50 | run: ./configure ${{ matrix.args }} 51 | - name: make 52 | if: matrix.os != 'windows-latest' && matrix.platform != 'android' 53 | run: make 54 | # Upload artifact 55 | - name: upload artifact 56 | if: matrix.platform != '' 57 | uses: actions/upload-artifact@master 58 | with: 59 | name: ${{format('pvr.chinachu.{0}-{1}-{2}', matrix.os, matrix.platform, github.sha)}} 60 | path: dist/pvr.chinachu 61 | 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # Build intermediate files 31 | Makefile 32 | config.log 33 | config.status 34 | .deps 35 | libtool 36 | Makefile.in 37 | aclocal.m4 38 | autom4te.cache/ 39 | compile 40 | config.* 41 | configure 42 | depcomp 43 | install-sh 44 | ltmain.sh 45 | m4/ 46 | missing 47 | obj/ 48 | libs/ 49 | dist/ 50 | 51 | *.pvr 52 | *.dll 53 | *.zip 54 | -------------------------------------------------------------------------------- /ChangeLog.txt: -------------------------------------------------------------------------------- 1 | v5.0.0 2 | - Support Kodi 18 Leia 3 | 4 | v4.0.0 5 | - Support Kodi 17 Krypton 6 | - Add channel logo icon 7 | - Add new genre codes 8 | - Add pattern matched rule creation 9 | - Add list force-refresh client action into menu 10 | - Add scheduler execution client action into menu 11 | - Add rule availability status change method 12 | - Add read-only timer rule list 13 | - Add initial settings failure alert 14 | - Skip listing up zero-programs channels 15 | - Remove recorded program grouping option 16 | - Remove ongoing recording playback option 17 | - Unsupport mirakurun direct watch 18 | - Support Raspberry Pi independent target binary 19 | - Support iOS arm build target (beta) 20 | 21 | v3.3.0 22 | - Support Chinachu gamma 23 | 24 | v3.2.0 25 | - Support service ID for mirakurun live watching 26 | 27 | v3.1.0 28 | - Add recording item grouping force disable option 29 | 30 | v3.0.0 31 | - Change project name to 'Harekaze for Kodi' 32 | - Support Mirakurun live tv watching 33 | 34 | v2.1.0 35 | - Add recording item grouping option 36 | 37 | v2.0.2 38 | - Fix crash when chinachu provides no channel name 39 | - Fix crash when programs contain no category field 40 | 41 | v2.0.1 42 | - Fix Kodi.guilib dependency 43 | 44 | v2.0.0 45 | - New major version for Kodi Jarvis 16.x 46 | - Support canceling ongoing recording 47 | - Show episode information of recorded programs 48 | - Bug fix 49 | 50 | v1.2.0 51 | - Change disk storage availability update interval 52 | - Support playback ongoing recording (beta) 53 | - Bug fix 54 | 55 | v1.1.0 56 | - Support Kodi on Windows 57 | - Manual program reserving addition/deletion is available 58 | - Show recording disk space information 59 | - Bug fix 60 | 61 | v1.0.1 62 | - Bug fix 63 | 64 | v1.0.0 65 | - Support Kodi on ARM Linux 66 | - Show reserving timer 67 | - Enable audio/video transcoding option 68 | - Update thumbnail option 69 | - Bug fix 70 | 71 | v0.0.3 72 | - Support Kodi on Android 73 | - Show recorded TV show's thumbnail 74 | - Deletion of recorded TV shows is available 75 | - Enable colored TV guide with Kodisystem's genre type 76 | 77 | v0.0.2 78 | - Support recorded TV shows 79 | - Improve category type definition 80 | 81 | v0.0.1 82 | - Support Live TV watching 83 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src 2 | 3 | ACLOCAL_AMFLAGS = -I m4 4 | 5 | .PHONY: all 6 | all: 7 | $(MAKE) -C ./src 8 | mkdir -p dist 9 | cp -r template/pvr.chinachu dist/ 10 | cp ChangeLog.txt dist/pvr.chinachu/ 11 | cp LICENSE dist/pvr.chinachu/ 12 | cp src/$(ADDONNAME) dist/pvr.chinachu/$(ADDONNAME) 13 | $(STRIP) -x dist/pvr.chinachu/$(ADDONNAME) 14 | 15 | .PHONY: release 16 | release: all 17 | cd dist; zip -9 -r ../pvr.chinachu.zip ./pvr.chinachu 18 | 19 | .PHONY: clean 20 | clean: 21 | $(MAKE) clean -C ./src 22 | rm -rf ./dist/ 23 | rm -f ./pvr.chinachu.zip 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Harekaze for Kodi/XBMC 2 | Chinachu PVR addon for Kodi 3 | 4 | ![Deprecation Notice](https://img.shields.io/badge/%E2%9A%A0%20Notice-Deprecation-yellow?style=for-the-badge) 5 | 6 | _**This project is suspended because the project owner is no longer using and maintaining it.**_ 7 | 8 | [![Build status: master](https://img.shields.io/travis/Harekaze/pvr.chinachu/master.svg?maxAge=259200&style=flat-square)](https://travis-ci.org/Harekaze/pvr.chinachu/) 9 | [![AppVeyor](https://img.shields.io/appveyor/ci/mzyy94/pvr-chinachu.svg?maxAge=2592000&style=flat-square)](https://ci.appveyor.com/project/mzyy94/pvr-chinachu) 10 | [![GitHub release](https://img.shields.io/github/release/Harekaze/pvr.chinachu.svg?maxAge=259200&style=flat-square)](https://github.com/Harekaze/pvr.chinachu/releases) 11 | [![GitHub release downloads](https://img.shields.io/github/downloads/Harekaze/pvr.chinachu/total.svg?style=flat-square)](https://github.com/Harekaze/pvr.chinachu/releases) 12 | [![GitHub issues](https://img.shields.io/github/issues/Harekaze/pvr.chinachu.svg?style=flat-square)](https://github.com/Harekaze/pvr.chinachu/issues) 13 | [![GitHub stars](https://img.shields.io/github/stars/Harekaze/pvr.chinachu.svg?style=flat-square)](https://github.com/Harekaze/pvr.chinachu/stargazers) 14 | [![GitHub license](https://img.shields.io/badge/license-GPLv3-orange.svg?style=flat-square)](https://raw.githubusercontent.com/Harekaze/pvr.chinachu/master/LICENSE) 15 | 16 | ![fanart](/template/pvr.chinachu/fanart.png) 17 | 18 | ## Supported environment 19 | 20 | ### Backend 21 | - Chinachu gamma [a69d5e99b7](https://github.com/Chinachu/Chinachu/commit/a69d5e99b75ddd770146e65d6171704be28ec01a) 22 | 23 | ### Frontend 24 | - Kodi **18.x** Leia 25 | + for macOS 26 | + for Android ARM 27 | + for Linux x64 28 | + for Raspberry Pi 29 | + for Windows 30 | + for iOS (beta) 31 | + for tvOS (beta) 32 | 33 | #### Old versions 34 | 35 | | Tag | Kodi | Platforms 36 | |------------|:-----------------|:-- 37 | | v0.x, v1.x | Kodi 15 Isengard | macOS/Linux/Raspberry Pi/(Windows) 38 | | v2.x, v3.x | Kodi 16 Jarvis | macOS/Linux/Raspberry Pi/Windows/(Android) 39 | | v4.x | Kodi 17 Krypton | macOS/Linux/Raspberry Pi/Windows/Android/(iOS) 40 | | v5.x | Kodi 18 Leia | macOS/Linux/Raspberry Pi/Windows/Android/(iOS)/(tvOS) 41 | 42 | :warning: *No features backpors, No security backports* :warning: 43 | 44 | ## Latest release 45 | 46 | [pvr.chinachu/releases](https://github.com/Harekaze/pvr.chinachu/releases) 47 | 48 | ## Building from source 49 | 50 | ### Linux / macOS 51 | ```sh 52 | $ ./bootstrap 53 | $ ./configure 54 | $ make 55 | $ make release 56 | $ ls pvr.chinachu.zip 57 | ``` 58 | > TIPS: If a warning about AC_CHECK_HEADER_STDBOOL has occurred, install gnulib and execute bootstrap with 59 | > AUTORECONF_FLAGS option with gnulib's m4 directory (e.g. `AUTORECONF_FLAGS=-I/usr/share/gnulib/m4 ./bootstrap`) 60 | 61 | ### Android ARM 62 | *Android NDK is required.* 63 | 64 | ```sh 65 | $ ndk-build APP_ABI=armeabi-v7a 66 | $ ./jni/pack.sh APP_ABI=armeabi-v7a 67 | $ ls pvr.chinachu.zip 68 | ``` 69 | 70 | ### Windows 71 | 72 | Requirements: 73 | - Visual Studio 2019 74 | - PowerShell v5 75 | 76 | ```powershell 77 | > ./build.ps1 78 | > ls ./pvr.chinachu.zip 79 | ``` 80 | > TIPS: If a powershell warning about Execution Policies has occurred, run `Set-ExecutionPolocy Unrestricted` 81 | > with Administrator privileges. After building this project, run `Set-ExecutionPolocy RemoteSigned`, please. 82 | 83 | > NOTE: PowerShell command 'Compress-Archive' creates broken zip file. 84 | > Please unzip created archive yourself, and re-zip it with other compression tool. 85 | 86 | ### iOS 87 | ```sh 88 | $ ./bootstrap 89 | $ ./configure --host=arm-apple-darwin 90 | $ make 91 | $ ls pvr.chinachu.zip 92 | ``` 93 | > NOTE: iOS targeted package can't install to Kodi for iOS with zip installation. 94 | > You should build Kodi.app including pvr.chinachu addon. 95 | 96 | ## Installing 97 | 98 | 1. Build or download the appropriate version for your platform. 99 | 2. Launch Kodi. 100 | 3. Navigate to System -> Add-ons -> Install from zip file 101 | 4. Select the zip file which you get in first step. 102 | 103 | > NOTE: In some cases, Kodi for android installs addons into non-executable device. As a result, you need to do something more. 104 | > See [wiki/android-installation](https://github.com/Harekaze/pvr.chinachu/wiki/android-installation). 105 | 106 | ## Configuration 107 | 108 | See [wiki/configuration](https://github.com/Harekaze/pvr.chinachu/wiki/configuration) 109 | 110 | ## Contribution 111 | 112 | See [wiki/contribution](https://github.com/Harekaze/pvr.chinachu/wiki/contribution) 113 | 114 | ## License 115 | 116 | [GPLv3](LICENSE) 117 | -------------------------------------------------------------------------------- /VS2019/chinachu/chinachu.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4} 15 | chinachu 16 | 10.0.17763.0 17 | 18 | 19 | 20 | StaticLibrary 21 | true 22 | v142 23 | MultiByte 24 | 25 | 26 | StaticLibrary 27 | false 28 | v142 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | .lib 46 | 47 | 48 | 49 | Level3 50 | Disabled 51 | true 52 | ..\..\include;..\..\src 53 | NOMINMAX;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_USE_32BIT_TIME_T;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;__STDC_FORMAT_MACROS;__WINDOWS__;TARGET_WINDOWS;_WINDOWS;_MSVC;WIN32;_WINDLL;%(PreprocessorDefinitions) 54 | 55 | 56 | true 57 | 58 | 59 | 60 | 61 | Level3 62 | MaxSpeed 63 | true 64 | true 65 | true 66 | ..\..\include;..\..\src 67 | NOMINMAX;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_USE_32BIT_TIME_T;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;__STDC_FORMAT_MACROS;__WINDOWS__;TARGET_WINDOWS;_WINDOWS;_MSVC;WIN32;_WINDLL;%(PreprocessorDefinitions) 68 | MultiThreadedDLL 69 | 70 | 71 | true 72 | true 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /VS2019/chinachu/chinachu.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /VS2019/pvr.chinachu.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pvr_client", "pvr_client\pvr_client.vcxproj", "{C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chinachu", "chinachu\chinachu.vcxproj", "{7C081EBB-5B67-4F16-8421-654C46E7A8D4}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Debug|x64.ActiveCfg = Debug|Win32 19 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Debug|x64.Build.0 = Debug|Win32 20 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Debug|x86.ActiveCfg = Debug|Win32 21 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Debug|x86.Build.0 = Debug|Win32 22 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Release|x64.ActiveCfg = Release|x64 23 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Release|x64.Build.0 = Release|x64 24 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Release|x86.ActiveCfg = Release|Win32 25 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0}.Release|x86.Build.0 = Release|Win32 26 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Debug|x64.ActiveCfg = Debug|Win32 27 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Debug|x64.Build.0 = Debug|Win32 28 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Debug|x86.ActiveCfg = Debug|Win32 29 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Debug|x86.Build.0 = Debug|Win32 30 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Release|x64.ActiveCfg = Release|x64 31 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Release|x64.Build.0 = Release|x64 32 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Release|x86.ActiveCfg = Release|Win32 33 | {7C081EBB-5B67-4F16-8421-654C46E7A8D4}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /VS2019/pvr_client/pvr_client.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Harekaze/pvr.chinachu/2b12d3fc5460cdc95e19763a567647113f0e807d/VS2019/pvr_client/pvr_client.rc -------------------------------------------------------------------------------- /VS2019/pvr_client/pvr_client.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {C3B65033-2A88-4B45-8DDB-EC990CF0DEF0} 15 | pvr_client 16 | 10.0.17763.0 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | v142 23 | MultiByte 24 | 25 | 26 | DynamicLibrary 27 | false 28 | v142 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | .dll 46 | pvr.chinachu 47 | 48 | 49 | pvr.chinachu 50 | 51 | 52 | 53 | Level3 54 | Disabled 55 | true 56 | $(DefineConstants);NOMINMAX;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_USE_32BIT_TIME_T;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;__STDC_FORMAT_MACROS;__WINDOWS__;TARGET_WINDOWS;_WINDOWS;_MSVC;WIN32;_WINDLL;%(PreprocessorDefinitions) 57 | ..\..\include;..\..\src 58 | 59 | 60 | true 61 | 62 | 63 | 64 | 65 | Level3 66 | MaxSpeed 67 | true 68 | true 69 | true 70 | ..\..\include;..\..\src 71 | $(DefineConstants);NOMINMAX;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_USE_32BIT_TIME_T;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;__STDC_FORMAT_MACROS;__WINDOWS__;TARGET_WINDOWS;_WINDOWS;_MSVC;WIN32;_WINDLL;%(PreprocessorDefinitions) 72 | 73 | 74 | true 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | {7c081ebb-5b67-4f16-8421-654c46e7a8d4} 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /VS2019/pvr_client/pvr_client.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | 47 | 48 | Header Files 49 | 50 | 51 | 52 | 53 | Resource Files 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /VS2019/pvr_client/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by pvr_client.rc 4 | 5 | // 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | 2 | echo -n "Checking for libtoolize... " 3 | LIBTOOLIZE=$(which glibtoolize || which libtoolize) 4 | if [ ! $? -eq 0 ]; then 5 | echo "not found." 6 | exit 1 7 | fi 8 | echo $LIBTOOLIZE 9 | 10 | echo -n "Checking for autoreconf... " 11 | AUTORECONF=$(which autoreconf) 12 | if [ ! $? -eq 0 ]; then 13 | echo "not found." 14 | exit 1 15 | fi 16 | echo $AUTORECONF 17 | 18 | echo 19 | 20 | echo "Running libtoolize..." 21 | $LIBTOOLIZE --copy --force --automake || ( echo "**FAILED**" ; exit 1 ) 22 | 23 | echo "Running autoreconf..." 24 | $AUTORECONF -i $AUTORECONF_FLAGS || ( echo "**FAILED**" ; exit 1 ) 25 | 26 | echo 27 | 28 | echo "Now, please run ./configure" 29 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | & ${env:ProgramFiles(x86)}\Microsoft` Visual` Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe .\VS2019\pvr.chinachu.sln /t:Clean,Build /p:Configuration=Release /p:Platform=x86 2 | New-Item dist -ItemType Directory 3 | Copy-Item -r .\template\pvr.chinachu .\dist\ 4 | Copy-Item .\ChangeLog.txt .\dist\pvr.chinachu 5 | Copy-Item .\LICENSE .\dist\pvr.chinachu 6 | Copy-Item .\VS2019\Release\pvr.chinachu.dll .\dist\pvr.chinachu 7 | Set-Location .\dist 8 | Compress-Archive -Force -CompressionLevel NoCompression -Path .\pvr.chinachu -DestinationPath ..\pvr.chinachu.zip 9 | Write-Warning "PowerShell command 'Compress-Archive' creates broken zip file. 10 | Please unzip .\pvr.chinachu.zip yourself, and re-zip it with other compression tool." 11 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.68]) 5 | AC_INIT([pvrchinachu], [5.0.0], [Harekaze project]) 6 | AC_CONFIG_MACRO_DIR([m4]) 7 | AM_INIT_AUTOMAKE([foreign]) 8 | LT_INIT 9 | 10 | ADDONNAME=pvr.chinachu.so 11 | LIBEXT=so 12 | 13 | case $host in 14 | arm-apple-darwin) 15 | ADDONNAME=pvr.chinachu-ios.dylib 16 | LIBEXT=dylib 17 | CXX=$(xcrun --sdk iphoneos --find clang++) 18 | LD=$(xcrun --sdk iphoneos --find ld) 19 | SYSROOT=$(xcrun --sdk iphoneos --show-sdk-path) 20 | AC_SUBST(AM_CPPFLAGS_EXT, "-arch arm64 -D__arm__ -isysroot $SYSROOT") 21 | AC_SUBST(LDFLAGS_EXT, "-arch arm64 -isysroot $SYSROOT") 22 | ;; 23 | *-apple-*) 24 | ADDONNAME=pvr.chinachu.dylib 25 | LIBEXT=dylib 26 | ;; 27 | arm*-*-linux-gnu*) 28 | ADDONNAME=pvr.chinachu.armel.so 29 | AC_SUBST(AM_CPPFLAGS_EXT, "-D_ARMEL") 30 | ;; 31 | esac 32 | 33 | AC_SUBST(ADDONNAME) 34 | AC_SUBST(LIBEXT) 35 | 36 | # Checks for programs. 37 | AC_PROG_CXX 38 | AC_PROG_CC 39 | 40 | # Checks for libraries. 41 | 42 | # Checks for header files. 43 | AC_CHECK_HEADERS([float.h inttypes.h locale.h stdint.h stdlib.h string.h]) 44 | 45 | # Checks for typedefs, structures, and compiler characteristics. 46 | AC_CHECK_HEADER_STDBOOL 47 | AC_C_INLINE 48 | AC_TYPE_INT64_T 49 | AC_TYPE_SIZE_T 50 | AC_TYPE_SSIZE_T 51 | AC_TYPE_UINT8_T 52 | 53 | # Checks for library functions. 54 | AC_FUNC_STRTOD 55 | AC_CHECK_FUNCS([localeconv memset modf select strdup]) 56 | 57 | AC_CONFIG_FILES([Makefile 58 | src/Makefile 59 | src/chinachu/Makefile 60 | src/pvr_client/Makefile]) 61 | AC_OUTPUT 62 | -------------------------------------------------------------------------------- /include/chinachu/genre.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_GENRE_H 23 | #define CHINACHU_GENRE_H 24 | #include 25 | #include 26 | 27 | namespace chinachu { 28 | static std::map iGenreTypePair = { 29 | {"anime", 0x55}, 30 | {"information", 0x22}, 31 | {"news", 0x21}, 32 | {"sports", 0x40}, 33 | {"variety", 0x32}, 34 | {"drama", 0x10}, 35 | {"music", 0x60}, 36 | {"cinema", 0x76}, 37 | {"documentary", 0x23}, 38 | {"theater", 0x30}, 39 | {"hobby", 0xa0}, 40 | {"welfare", 0x95}, 41 | {"etc", 0x00}, 42 | }; 43 | const unsigned char GENRE_TYPE_MASK = 0xf0; 44 | const unsigned char GENRE_SUBTYPE_MASK = 0x0f; 45 | } // namespace chinachu 46 | 47 | #endif /* end of include guard */ 48 | -------------------------------------------------------------------------------- /include/dlfcn-win32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * dlfcn-win32 4 | * Copyright (c) 2007 Ramiro Polla 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef DLFCN_H 22 | #define DLFCN_H 23 | 24 | /* POSIX says these are implementation-defined. 25 | * To simplify use with Windows API, we treat them the same way. 26 | */ 27 | 28 | #define RTLD_LAZY 0 29 | #define RTLD_NOW 0 30 | 31 | #define RTLD_GLOBAL (1 << 1) 32 | #define RTLD_LOCAL (1 << 2) 33 | 34 | /* These two were added in The Open Group Base Specifications Issue 6. 35 | * Note: All other RTLD_* flags in any dlfcn.h are not standard compliant. 36 | */ 37 | 38 | #define RTLD_DEFAULT 0 39 | #define RTLD_NEXT 0 40 | 41 | void *dlopen ( const char *file, int mode ); 42 | int dlclose( void *handle ); 43 | void *dlsym ( void *handle, const char *name ); 44 | char *dlerror( void ); 45 | 46 | #endif /* DLFCN-WIN32_H */ 47 | -------------------------------------------------------------------------------- /include/kodi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(HEADERS AddonBase.h 2 | Filesystem.h 3 | General.h 4 | Network.h 5 | StreamCodec.h 6 | StreamCrypto.h 7 | kodi_game_dll.h 8 | kodi_game_types.h 9 | kodi_vfs_types.h 10 | libKODI_game.h 11 | libKODI_guilib.h 12 | libXBMC_addon.h 13 | libXBMC_pvr.h 14 | versions.h 15 | xbmc_addon_dll.h 16 | xbmc_addon_types.h 17 | xbmc_epg_types.h 18 | xbmc_pvr_dll.h 19 | xbmc_pvr_types.h) 20 | 21 | if(CORE_SYSTEM_NAME STREQUAL android) 22 | list(APPEND SOURCES platform/android/System.h) 23 | endif() 24 | 25 | if(NOT ENABLE_STATIC_LIBS) 26 | core_add_library(addons_kodi-addon-dev-kit_include_kodi) 27 | endif() 28 | -------------------------------------------------------------------------------- /include/kodi/NOTE: -------------------------------------------------------------------------------- 1 | NOTE: 2 | 3 | This directory contains independent Headers to build Add-on's 4 | without the whole Kodi source tree. The Add-on itself can add 5 | this headers to his source tree without dependencies to any 6 | Kodi related classes or functions. 7 | 8 | Also this headers are never changed without a API Version 9 | change. 10 | 11 | The current PVR API version can be found in xbmc_pvr_types.h: 12 | XBMC_PVR_API_VERSION 13 | -------------------------------------------------------------------------------- /include/kodi/Network.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "AddonBase.h" 12 | 13 | /* 14 | * For interface between add-on and kodi. 15 | * 16 | * This structure defines the addresses of functions stored inside Kodi which 17 | * are then available for the add-on to call 18 | * 19 | * All function pointers there are used by the C++ interface functions below. 20 | * You find the set of them on xbmc/addons/interfaces/General.cpp 21 | * 22 | * Note: For add-on development itself this is not needed 23 | */ 24 | typedef struct AddonToKodiFuncTable_kodi_network 25 | { 26 | bool (*wake_on_lan)(void* kodiBase, const char *mac); 27 | char* (*get_ip_address)(void* kodiBase); 28 | char* (*dns_lookup)(void* kodiBase, const char* url, bool* ret); 29 | char* (*url_encode)(void* kodiBase, const char* url); 30 | } AddonToKodiFuncTable_kodi_network; 31 | 32 | //============================================================================== 33 | /// 34 | /// \defgroup cpp_kodi_network Interface - kodi::network 35 | /// \ingroup cpp 36 | /// @brief **Network functions** 37 | /// 38 | /// The network module offers functions that allow you to control it. 39 | /// 40 | /// It has the header \ref Network.h "#include " be included 41 | /// to enjoy it. 42 | /// 43 | //------------------------------------------------------------------------------ 44 | 45 | namespace kodi 46 | { 47 | namespace network 48 | { 49 | 50 | //============================================================================ 51 | /// 52 | /// \ingroup cpp_kodi_network 53 | /// @brief Send WakeOnLan magic packet. 54 | /// 55 | /// @param[in] mac Network address of the host to wake. 56 | /// @return True if the magic packet was successfully sent, false otherwise. 57 | /// 58 | inline bool WakeOnLan(const std::string& mac) 59 | { 60 | return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->wake_on_lan(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, mac.c_str()); 61 | } 62 | //---------------------------------------------------------------------------- 63 | 64 | //============================================================================ 65 | /// 66 | /// \ingroup cpp_kodi_network 67 | /// @brief To the current own ip address as a string. 68 | /// 69 | /// @return Own system ip. 70 | /// 71 | /// 72 | /// ------------------------------------------------------------------------ 73 | /// 74 | /// **Example:** 75 | /// ~~~~~~~~~~~~~{.cpp} 76 | /// #include 77 | /// ... 78 | /// std::string ipAddress = kodi::network::GetIPAddress(); 79 | /// fprintf(stderr, "My IP is '%s'\n", ipAddress.c_str()); 80 | /// ... 81 | /// ~~~~~~~~~~~~~ 82 | /// 83 | inline std::string GetIPAddress() 84 | { 85 | std::string ip; 86 | char* string = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->get_ip_address(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase); 87 | if (string != nullptr) 88 | { 89 | ip = string; 90 | ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, string); 91 | } 92 | return ip; 93 | } 94 | //---------------------------------------------------------------------------- 95 | 96 | //============================================================================ 97 | /// 98 | /// \ingroup cpp_kodi_network 99 | /// @brief URL encodes the given string 100 | /// 101 | /// This function converts the given input string to a URL encoded string and 102 | /// returns that as a new allocated string. All input characters that are 103 | /// not a-z, A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped" 104 | /// version (%NN where NN is a two-digit hexadecimal number). 105 | /// 106 | /// @param[in] url The code of the message to get. 107 | /// @return Encoded URL string 108 | /// 109 | /// 110 | /// ------------------------------------------------------------------------ 111 | /// 112 | /// **Example:** 113 | /// ~~~~~~~~~~~~~{.cpp} 114 | /// #include 115 | /// ... 116 | /// std::string encodedUrl = kodi::network::URLEncode("François"); 117 | /// fprintf(stderr, "Encoded URL is '%s'\n", encodedUrl.c_str()); 118 | /// ... 119 | /// ~~~~~~~~~~~~~ 120 | /// For example, the string: François ,would be encoded as: Fran%C3%A7ois 121 | /// 122 | inline std::string URLEncode(const std::string& url) 123 | { 124 | std::string retString; 125 | char* string = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->url_encode(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, url.c_str()); 126 | if (string != nullptr) 127 | { 128 | retString = string; 129 | ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, string); 130 | } 131 | return retString; 132 | } 133 | //---------------------------------------------------------------------------- 134 | 135 | //============================================================================ 136 | /// 137 | /// \ingroup cpp_kodi_network 138 | /// @brief Lookup URL in DNS cache 139 | /// 140 | /// This test will get DNS record for a domain. The DNS lookup is done directly 141 | /// against the domain's authoritative name server, so changes to DNS Records 142 | /// should show up instantly. By default, the DNS lookup tool will return an 143 | /// IP address if you give it a name (e.g. www.example.com) 144 | /// 145 | /// @param[in] hostName The code of the message to get. 146 | /// @param[out] ipAddress Returned address 147 | /// @return true if successfull 148 | /// 149 | /// 150 | /// ------------------------------------------------------------------------ 151 | /// 152 | /// **Example:** 153 | /// ~~~~~~~~~~~~~{.cpp} 154 | /// #include 155 | /// ... 156 | /// std::string ipAddress; 157 | /// bool ret = kodi::network::DNSLookup("www.google.com", ipAddress); 158 | /// fprintf(stderr, "DNSLookup returned for www.google.com the IP '%s', call was %s\n", ipAddress.c_str(), ret ? "ok" : "failed"); 159 | /// ... 160 | /// ~~~~~~~~~~~~~ 161 | /// 162 | inline bool DNSLookup(const std::string& hostName, std::string& ipAddress) 163 | { 164 | bool ret = false; 165 | char* string = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->dns_lookup(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, hostName.c_str(), &ret); 166 | if (string != nullptr) 167 | { 168 | ipAddress = string; 169 | ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, string); 170 | } 171 | return ret; 172 | } 173 | //---------------------------------------------------------------------------- 174 | 175 | } /* namespace network */ 176 | } /* namespace kodi */ 177 | -------------------------------------------------------------------------------- /include/kodi/StreamCodec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | enum STREAMCODEC_PROFILE 12 | { 13 | CodecProfileUnknown = 0, 14 | CodecProfileNotNeeded, 15 | H264CodecProfileBaseline, 16 | H264CodecProfileMain, 17 | H264CodecProfileExtended, 18 | H264CodecProfileHigh, 19 | H264CodecProfileHigh10, 20 | H264CodecProfileHigh422, 21 | H264CodecProfileHigh444Predictive 22 | }; 23 | -------------------------------------------------------------------------------- /include/kodi/StreamCrypto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | typedef struct CRYPTO_INFO 12 | { 13 | enum CRYPTO_KEY_SYSTEM : uint8_t 14 | { 15 | CRYPTO_KEY_SYSTEM_NONE = 0, 16 | CRYPTO_KEY_SYSTEM_WIDEVINE, 17 | CRYPTO_KEY_SYSTEM_PLAYREADY, 18 | CRYPTO_KEY_SYSTEM_COUNT 19 | } m_CryptoKeySystem; /*!< @brief keysystem for encrypted media, KEY_SYSTEM_NONE for unencrypted media */ 20 | 21 | static const uint8_t FLAG_SECURE_DECODER = 1; /*!< @brief is set in flags if decoding has to be done in TEE environment */ 22 | 23 | uint8_t flags; 24 | uint16_t m_CryptoSessionIdSize; /*!< @brief The size of the crypto session key id */ 25 | const char *m_CryptoSessionId; /*!< @brief The crypto session key id */ 26 | } CRYPTO_INFO; 27 | -------------------------------------------------------------------------------- /include/kodi/addon-instance/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(HEADERS AudioDecoder.h 2 | AudioEncoder.h 3 | ImageDecoder.h 4 | Inputstream.h 5 | Peripheral.h 6 | PeripheralUtils.h 7 | Screensaver.h 8 | VFS.h 9 | VideoCodec.h 10 | Visualization.h) 11 | 12 | if(NOT ENABLE_STATIC_LIBS) 13 | core_add_library(addons_kodi-addon-dev-kit_include_kodi_addon-instance) 14 | endif() 15 | -------------------------------------------------------------------------------- /include/kodi/addon-instance/ImageDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../AddonBase.h" 12 | 13 | namespace kodi { namespace addon { class CInstanceImageDecoder; }} 14 | 15 | extern "C" 16 | { 17 | 18 | typedef struct AddonProps_ImageDecoder 19 | { 20 | const char* mimetype; 21 | } AddonProps_ImageDecoder; 22 | 23 | typedef struct AddonToKodiFuncTable_ImageDecoder 24 | { 25 | KODI_HANDLE kodi_instance; 26 | } AddonToKodiFuncTable_ImageDecoder; 27 | 28 | struct AddonInstance_ImageDecoder; 29 | typedef struct KodiToAddonFuncTable_ImageDecoder 30 | { 31 | kodi::addon::CInstanceImageDecoder* addonInstance; 32 | bool (__cdecl* load_image_from_memory) (const AddonInstance_ImageDecoder* instance, 33 | unsigned char* buffer, unsigned int buf_size, 34 | unsigned int* width, unsigned int* height); 35 | 36 | bool (__cdecl* decode) (const AddonInstance_ImageDecoder* instance, 37 | unsigned char* pixels, 38 | unsigned int width, unsigned int height, 39 | unsigned int pitch, unsigned int format); 40 | } KodiToAddonFuncTable_ImageDecoder; 41 | 42 | typedef struct AddonInstance_ImageDecoder 43 | { 44 | AddonProps_ImageDecoder props; 45 | AddonToKodiFuncTable_ImageDecoder toKodi; 46 | KodiToAddonFuncTable_ImageDecoder toAddon; 47 | } AddonInstance_ImageDecoder; 48 | 49 | } /* extern "C" */ 50 | 51 | typedef enum ImageFormat : unsigned int 52 | { 53 | ADDON_IMG_FMT_A8R8G8B8 = 1, 54 | ADDON_IMG_FMT_A8 = 2, 55 | ADDON_IMG_FMT_RGBA8 = 3, 56 | ADDON_IMG_FMT_RGB8 = 4 57 | } ImageFormat; 58 | 59 | namespace kodi 60 | { 61 | namespace addon 62 | { 63 | 64 | class CInstanceImageDecoder : public IAddonInstance 65 | { 66 | public: 67 | //========================================================================== 68 | /// @brief Class constructor 69 | /// 70 | /// @param[in] instance The from Kodi given instance given be 71 | /// add-on CreateInstance call with instance 72 | /// id ADDON_INSTANCE_IMAGEDECODER. 73 | explicit CInstanceImageDecoder(KODI_HANDLE instance) 74 | : IAddonInstance(ADDON_INSTANCE_IMAGEDECODER) 75 | { 76 | if (CAddonBase::m_interface->globalSingleInstance != nullptr) 77 | throw std::logic_error("kodi::addon::CInstanceImageDecoder: Creation of multiple together with single instance way is not allowed!"); 78 | 79 | SetAddonStruct(instance); 80 | } 81 | //-------------------------------------------------------------------------- 82 | 83 | ~CInstanceImageDecoder() override = default; 84 | 85 | //========================================================================== 86 | /// @brief Initialize an encoder 87 | /// 88 | /// @param[in] buffer The data to read from memory 89 | /// @param[in] bufSize The buffer size 90 | /// @param[in,out] width The optimal width of image on entry, obtained width on return 91 | /// @param[in,out] height The optimal height of image, actual obtained height on return 92 | /// @return true if successful done, false on error 93 | /// 94 | virtual bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, 95 | unsigned int& width, unsigned int& height) = 0; 96 | //-------------------------------------------------------------------------- 97 | 98 | //========================================================================== 99 | /// @brief Decode previously loaded image 100 | /// 101 | /// @param[in] pixels Output buffer 102 | /// @param[in] width Width of output image 103 | /// @param[in] height Height of output image 104 | /// @param[in] pitch Pitch of output image 105 | /// @param[in] format Format of output image 106 | /// @return true if successful done, false on error 107 | /// 108 | virtual bool Decode(unsigned char* pixels, 109 | unsigned int width, unsigned int height, 110 | unsigned int pitch, ImageFormat format) = 0; 111 | //-------------------------------------------------------------------------- 112 | 113 | //========================================================================== 114 | /// @brief Get the wanted mime type from Kodi 115 | /// 116 | /// @return the mimetype wanted from Kodi 117 | /// 118 | inline std::string MimeType() { return m_instanceData->props.mimetype; } 119 | //-------------------------------------------------------------------------- 120 | 121 | private: 122 | void SetAddonStruct(KODI_HANDLE instance) 123 | { 124 | if (instance == nullptr) 125 | throw std::logic_error("kodi::addon::CInstanceImageDecoder: Creation with empty addon structure not allowed, table must be given from Kodi!"); 126 | 127 | m_instanceData = static_cast(instance); 128 | m_instanceData->toAddon.addonInstance = this; 129 | m_instanceData->toAddon.load_image_from_memory = ADDON_LoadImageFromMemory; 130 | m_instanceData->toAddon.decode = ADDON_Decode; 131 | } 132 | 133 | inline static bool ADDON_LoadImageFromMemory(const AddonInstance_ImageDecoder* instance, 134 | unsigned char* buffer, unsigned int bufSize, 135 | unsigned int* width, unsigned int* height) 136 | { 137 | return instance->toAddon.addonInstance->LoadImageFromMemory(buffer, bufSize, *width, *height); 138 | } 139 | 140 | inline static bool ADDON_Decode(const AddonInstance_ImageDecoder* instance, 141 | unsigned char* pixels, 142 | unsigned int width, unsigned int height, 143 | unsigned int pitch, unsigned int format) 144 | { 145 | return instance->toAddon.addonInstance->Decode(pixels, width, height, pitch, static_cast(format)); 146 | } 147 | 148 | AddonInstance_ImageDecoder* m_instanceData; 149 | }; 150 | 151 | } /* namespace addon */ 152 | } /* namespace kodi */ 153 | -------------------------------------------------------------------------------- /include/kodi/addon-instance/VideoCodec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../AddonBase.h" 12 | #include "../StreamCrypto.h" 13 | #include "../StreamCodec.h" 14 | 15 | #ifdef BUILD_KODI_ADDON 16 | #include "../DemuxPacket.h" 17 | #else 18 | #include "cores/VideoPlayer/Interface/Addon/DemuxPacket.h" 19 | #endif 20 | 21 | namespace kodi { namespace addon { class CInstanceVideoCodec; } } 22 | 23 | extern "C" 24 | { 25 | enum VIDEOCODEC_FORMAT 26 | { 27 | UnknownVideoFormat = 0, 28 | VideoFormatYV12, 29 | VideoFormatI420, 30 | MaxVideoFormats 31 | }; 32 | 33 | 34 | struct VIDEOCODEC_INITDATA 35 | { 36 | enum Codec { 37 | CodecUnknown = 0, 38 | CodecVp8, 39 | CodecH264, 40 | CodecVp9 41 | } codec; 42 | 43 | STREAMCODEC_PROFILE codecProfile; 44 | 45 | //UnknownVideoFormat is terminator 46 | VIDEOCODEC_FORMAT *videoFormats; 47 | 48 | uint32_t width, height; 49 | 50 | const uint8_t *extraData; 51 | unsigned int extraDataSize; 52 | 53 | CRYPTO_INFO cryptoInfo; 54 | }; 55 | 56 | struct VIDEOCODEC_PICTURE 57 | { 58 | enum VideoPlane { 59 | YPlane = 0, 60 | UPlane, 61 | VPlane, 62 | MaxPlanes = 3, 63 | }; 64 | 65 | enum Flags : uint32_t { 66 | FLAG_DROP, 67 | FLAG_DRAIN 68 | }; 69 | 70 | VIDEOCODEC_FORMAT videoFormat; 71 | uint32_t flags; 72 | 73 | uint32_t width, height; 74 | 75 | uint8_t *decodedData; 76 | size_t decodedDataSize; 77 | 78 | uint32_t planeOffsets[VideoPlane::MaxPlanes]; 79 | uint32_t stride[VideoPlane::MaxPlanes]; 80 | 81 | int64_t pts; 82 | 83 | void *buffer; //< will be passed in release_frame_buffer 84 | }; 85 | 86 | enum VIDEOCODEC_RETVAL 87 | { 88 | VC_NONE = 0, //< noop 89 | VC_ERROR, //< an error occured, no other messages will be returned 90 | VC_BUFFER, //< the decoder needs more data 91 | VC_PICTURE, //< the decoder got a picture 92 | VC_EOF, //< the decoder signals EOF 93 | }; 94 | 95 | // this are properties given to the addon on create 96 | // at this time we have no parameters for the addon 97 | typedef struct AddonProps_VideoCodec 98 | { 99 | int dummy; 100 | } AddonProps_VideoCodec; 101 | 102 | struct AddonInstance_VideoCodec; 103 | typedef struct KodiToAddonFuncTable_VideoCodec 104 | { 105 | kodi::addon::CInstanceVideoCodec* addonInstance; 106 | 107 | //! \brief Opens a codec 108 | bool (__cdecl* open) (const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData); 109 | 110 | //! \brief Reconfigures a codec 111 | bool (__cdecl* reconfigure) (const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData); 112 | 113 | //! \brief Feed codec if requested from GetPicture() (return VC_BUFFER) 114 | bool (__cdecl* add_data) (const AddonInstance_VideoCodec* instance, const DemuxPacket *packet); 115 | 116 | //! \brief Get a decoded picture / request new data 117 | VIDEOCODEC_RETVAL (__cdecl* get_picture) (const AddonInstance_VideoCodec* instance, VIDEOCODEC_PICTURE *picture); 118 | 119 | //! \brief Get the name of this video decoder 120 | const char *(__cdecl* get_name) (const AddonInstance_VideoCodec* instance); 121 | 122 | //! \brief Reset the codec 123 | void (__cdecl* reset)(const AddonInstance_VideoCodec* instance); 124 | } KodiToAddonFuncTable_VideoCodec; 125 | 126 | typedef struct AddonToKodiFuncTable_VideoCodec 127 | { 128 | KODI_HANDLE kodiInstance; 129 | bool(*get_frame_buffer)(void* kodiInstance, VIDEOCODEC_PICTURE *picture); 130 | void(*release_frame_buffer)(void* kodiInstance, void *buffer); 131 | } AddonToKodiFuncTable_VideoCodec; 132 | 133 | typedef struct AddonInstance_VideoCodec 134 | { 135 | AddonProps_VideoCodec props; 136 | AddonToKodiFuncTable_VideoCodec toKodi; 137 | KodiToAddonFuncTable_VideoCodec toAddon; 138 | } AddonInstance_VideoCodec; 139 | } 140 | 141 | namespace kodi 142 | { 143 | namespace addon 144 | { 145 | 146 | class CInstanceVideoCodec : public IAddonInstance 147 | { 148 | public: 149 | explicit CInstanceVideoCodec(KODI_HANDLE instance) 150 | : IAddonInstance(ADDON_INSTANCE_VIDEOCODEC) 151 | { 152 | if (CAddonBase::m_interface->globalSingleInstance != nullptr) 153 | throw std::logic_error("kodi::addon::CInstanceVideoCodec: Creation of multiple together with single instance way is not allowed!"); 154 | 155 | SetAddonStruct(instance); 156 | } 157 | 158 | ~CInstanceVideoCodec() override = default; 159 | 160 | //! \copydoc CInstanceVideoCodec::Open 161 | virtual bool Open(VIDEOCODEC_INITDATA &initData) { return false; }; 162 | 163 | //! \copydoc CInstanceVideoCodec::Reconfigure 164 | virtual bool Reconfigure(VIDEOCODEC_INITDATA &initData) { return false; }; 165 | 166 | //! \copydoc CInstanceVideoCodec::AddData 167 | virtual bool AddData(const DemuxPacket &packet) { return false; }; 168 | 169 | //! \copydoc CInstanceVideoCodec::GetPicture 170 | virtual VIDEOCODEC_RETVAL GetPicture(VIDEOCODEC_PICTURE &picture) { return VC_ERROR; }; 171 | 172 | //! \copydoc CInstanceVideoCodec::GetName 173 | virtual const char *GetName() { return nullptr; }; 174 | 175 | //! \copydoc CInstanceVideoCodec::Reset 176 | virtual void Reset() {}; 177 | 178 | /*! 179 | * @brief AddonToKodi interface 180 | */ 181 | 182 | //! \copydoc CInstanceVideoCodec::GetFrameBuffer 183 | bool GetFrameBuffer(VIDEOCODEC_PICTURE &picture) 184 | { 185 | return m_instanceData->toKodi.get_frame_buffer(m_instanceData->toKodi.kodiInstance, &picture); 186 | } 187 | 188 | //! \copydoc CInstanceVideoCodec::ReleaseFrameBuffer 189 | void ReleaseFrameBuffer(void *buffer) 190 | { 191 | return m_instanceData->toKodi.release_frame_buffer(m_instanceData->toKodi.kodiInstance, buffer); 192 | } 193 | 194 | private: 195 | void SetAddonStruct(KODI_HANDLE instance) 196 | { 197 | if (instance == nullptr) 198 | throw std::logic_error("kodi::addon::CInstanceVideoCodec: Creation with empty addon structure not allowed, table must be given from Kodi!"); 199 | 200 | m_instanceData = static_cast(instance); 201 | 202 | m_instanceData->toAddon.addonInstance = this; 203 | m_instanceData->toAddon.open = ADDON_Open; 204 | m_instanceData->toAddon.reconfigure = ADDON_Reconfigure; 205 | m_instanceData->toAddon.add_data = ADDON_AddData; 206 | m_instanceData->toAddon.get_picture = ADDON_GetPicture; 207 | m_instanceData->toAddon.get_name = ADDON_GetName; 208 | m_instanceData->toAddon.reset = ADDON_Reset; 209 | } 210 | 211 | inline static bool ADDON_Open(const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData) 212 | { 213 | return instance->toAddon.addonInstance->Open(*initData); 214 | } 215 | 216 | inline static bool ADDON_Reconfigure(const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData) 217 | { 218 | return instance->toAddon.addonInstance->Reconfigure(*initData); 219 | } 220 | 221 | inline static bool ADDON_AddData(const AddonInstance_VideoCodec* instance, const DemuxPacket *packet) 222 | { 223 | return instance->toAddon.addonInstance->AddData(*packet); 224 | } 225 | 226 | inline static VIDEOCODEC_RETVAL ADDON_GetPicture(const AddonInstance_VideoCodec* instance, VIDEOCODEC_PICTURE *picture) 227 | { 228 | return instance->toAddon.addonInstance->GetPicture(*picture); 229 | } 230 | 231 | inline static const char *ADDON_GetName(const AddonInstance_VideoCodec* instance) 232 | { 233 | return instance->toAddon.addonInstance->GetName(); 234 | } 235 | 236 | inline static void ADDON_Reset(const AddonInstance_VideoCodec* instance) 237 | { 238 | return instance->toAddon.addonInstance->Reset(); 239 | } 240 | 241 | AddonInstance_VideoCodec* m_instanceData; 242 | }; 243 | } // namespace addon 244 | } // namespace kodi 245 | -------------------------------------------------------------------------------- /include/kodi/filesystem/IFileTypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace XFILE 14 | { 15 | 16 | /* indicate that caller can handle truncated reads, where function returns before entire buffer has been filled */ 17 | static const unsigned int READ_TRUNCATED = 0x01; 18 | 19 | /* indicate that that caller support read in the minimum defined chunk size, this disables internal cache then */ 20 | static const unsigned int READ_CHUNKED = 0x02; 21 | 22 | /* use cache to access this file */ 23 | static const unsigned int READ_CACHED = 0x04; 24 | 25 | /* open without caching. regardless to file type. */ 26 | static const unsigned int READ_NO_CACHE = 0x08; 27 | 28 | /* calculate bitrate for file while reading */ 29 | static const unsigned int READ_BITRATE = 0x10; 30 | 31 | /* indicate to the caller we will seek between multiple streams in the file frequently */ 32 | static const unsigned int READ_MULTI_STREAM = 0x20; 33 | 34 | /* indicate to the caller file is audio and/or video (and e.g. may grow) */ 35 | static const unsigned int READ_AUDIO_VIDEO = 0x40; 36 | 37 | /* indicate that caller will do write operations before reading */ 38 | static const unsigned int READ_AFTER_WRITE = 0x80; 39 | 40 | /* indicate that caller want to reopen a file if its already open */ 41 | static const unsigned int READ_REOPEN = 0x100; 42 | 43 | struct SNativeIoControl 44 | { 45 | unsigned long int request; 46 | void* param; 47 | }; 48 | 49 | struct SCacheStatus 50 | { 51 | uint64_t forward; /**< number of bytes cached forward of current position */ 52 | unsigned maxrate; /**< maximum number of bytes per second cache is allowed to fill */ 53 | unsigned currate; /**< average read rate from source file since last position change */ 54 | bool lowspeed; /**< cache low speed condition detected? */ 55 | }; 56 | 57 | typedef enum { 58 | IOCTRL_NATIVE = 1, /**< SNativeIoControl structure, containing what should be passed to native ioctrl */ 59 | IOCTRL_SEEK_POSSIBLE = 2, /**< return 0 if known not to work, 1 if it should work */ 60 | IOCTRL_CACHE_STATUS = 3, /**< SCacheStatus structure */ 61 | IOCTRL_CACHE_SETRATE = 4, /**< unsigned int with speed limit for caching in bytes per second */ 62 | IOCTRL_SET_CACHE = 8, /**< CFileCache */ 63 | IOCTRL_SET_RETRY = 16, /**< Enable/disable retry within the protocol handler (if supported) */ 64 | } EIoControl; 65 | 66 | enum CURLOPTIONTYPE 67 | { 68 | CURL_OPTION_OPTION, /**< Set a general option */ 69 | CURL_OPTION_PROTOCOL, /**< Set a protocol option (see below) */ 70 | CURL_OPTION_CREDENTIALS,/**< Set User and password */ 71 | CURL_OPTION_HEADER /**< Add a Header */ 72 | }; 73 | 74 | /** 75 | * The following names for CURL_OPTION_PROTOCOL are possible: 76 | * 77 | * accept-charset: Set the "accept-charset" header 78 | * acceptencoding or encoding: Set the "accept-encoding" header 79 | * active-remote: Set the "active-remote" header 80 | * auth: Set the authentication method. Possible values: any, anysafe, digest, ntlm 81 | * connection-timeout: Set the connection timeout in seconds 82 | * cookie: Set the "cookie" header 83 | * customrequest: Set a custom HTTP request like DELETE 84 | * noshout: Set to true if kodi detects a stream as shoutcast by mistake. 85 | * postdata: Set the post body (value needs to be base64 encoded). (Implicitly sets the request to POST) 86 | * referer: Set the "referer" header 87 | * user-agent: Set the "user-agent" header 88 | * seekable: Set the stream seekable. 1: enable, 0: disable 89 | * sslcipherlist: Set list of accepted SSL ciphers. 90 | */ 91 | 92 | enum FileProperty 93 | { 94 | FILE_PROPERTY_RESPONSE_PROTOCOL, /**< Get response protocol line */ 95 | FILE_PROPERTY_RESPONSE_HEADER, /**< Get response Header value */ 96 | FILE_PROPERTY_CONTENT_TYPE, /**< Get file content-type */ 97 | FILE_PROPERTY_CONTENT_CHARSET, /**< Get file content charset */ 98 | FILE_PROPERTY_MIME_TYPE, /**< Get file mime type */ 99 | FILE_PROPERTY_EFFECTIVE_URL /**< Get effective URL for redirected streams */ 100 | }; 101 | 102 | } 103 | -------------------------------------------------------------------------------- /include/kodi/gui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(HEADERS General.h 2 | ListItem.h 3 | Window.h 4 | definitions.h) 5 | 6 | if(NOT ENABLE_STATIC_LIBS) 7 | core_add_library(addons_kodi-addon-dev-kit_include_kodi_gui) 8 | endif() 9 | -------------------------------------------------------------------------------- /include/kodi/gui/General.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../AddonBase.h" 12 | #include "definitions.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | 19 | //============================================================================ 20 | /// 21 | // \defgroup cpp_kodi_gui ::general 22 | /// \addtogroup cpp_kodi_gui 23 | /// @{ 24 | /// @brief **Allow use of binary classes and function to use on add-on's** 25 | /// 26 | /// Permits the use of the required functions of the add-on to Kodi. This class 27 | /// also contains some functions to the control. 28 | /// 29 | /// These are pure functions them no other initialization need. 30 | /// 31 | /// It has the header \ref kodi/gui/General.h "#include " be included 32 | /// to enjoy it. 33 | /// 34 | 35 | //========================================================================== 36 | /// 37 | /// \ingroup cpp_kodi_gui 38 | /// @brief Performs a graphical lock of rendering engine 39 | /// 40 | inline void Lock() 41 | { 42 | using namespace ::kodi::addon; 43 | CAddonBase::m_interface->toKodi->kodi_gui->general->lock(); 44 | } 45 | 46 | //-------------------------------------------------------------------------- 47 | 48 | //========================================================================== 49 | /// 50 | /// \ingroup cpp_kodi_gui 51 | /// @brief Performs a graphical unlock of previous locked rendering engine 52 | /// 53 | inline void Unlock() 54 | { 55 | using namespace ::kodi::addon; 56 | CAddonBase::m_interface->toKodi->kodi_gui->general->unlock(); 57 | } 58 | //-------------------------------------------------------------------------- 59 | 60 | //========================================================================== 61 | /// 62 | /// \ingroup cpp_kodi_gui 63 | /// @brief Return the the current screen height with pixel 64 | /// 65 | inline int GetScreenHeight() 66 | { 67 | using namespace ::kodi::addon; 68 | return CAddonBase::m_interface->toKodi->kodi_gui->general->get_screen_height(CAddonBase::m_interface->toKodi->kodiBase); 69 | } 70 | //-------------------------------------------------------------------------- 71 | 72 | //========================================================================== 73 | /// 74 | /// \ingroup cpp_kodi_gui 75 | /// @brief Return the the current screen width with pixel 76 | /// 77 | inline int GetScreenWidth() 78 | { 79 | using namespace ::kodi::addon; 80 | return CAddonBase::m_interface->toKodi->kodi_gui->general->get_screen_width(CAddonBase::m_interface->toKodi->kodiBase); 81 | } 82 | //-------------------------------------------------------------------------- 83 | 84 | //========================================================================== 85 | /// 86 | /// \ingroup cpp_kodi_gui 87 | /// @brief Return the the current screen rendering resolution 88 | /// 89 | inline int GetVideoResolution() 90 | { 91 | using namespace ::kodi::addon; 92 | return CAddonBase::m_interface->toKodi->kodi_gui->general->get_video_resolution(CAddonBase::m_interface->toKodi->kodiBase); 93 | } 94 | //-------------------------------------------------------------------------- 95 | 96 | //========================================================================== 97 | /// 98 | /// \ingroup cpp_kodi_gui 99 | /// @brief Returns the id for the current 'active' dialog as an integer. 100 | /// 101 | /// @return The currently active dialog Id 102 | /// 103 | /// 104 | ///------------------------------------------------------------------------- 105 | /// 106 | /// **Example:** 107 | /// ~~~~~~~~~~~~~{.cpp} 108 | /// .. 109 | /// int wid = kodi::gui::GetCurrentWindowDialogId() 110 | /// .. 111 | /// ~~~~~~~~~~~~~ 112 | /// 113 | inline int GetCurrentWindowDialogId() 114 | { 115 | using namespace ::kodi::addon; 116 | return CAddonBase::m_interface->toKodi->kodi_gui->general->get_current_window_dialog_id(CAddonBase::m_interface->toKodi->kodiBase); 117 | } 118 | //-------------------------------------------------------------------------- 119 | 120 | //========================================================================== 121 | /// 122 | /// \ingroup cpp_kodi_gui 123 | /// @brief Returns the id for the current 'active' window as an integer. 124 | /// 125 | /// @return The currently active window Id 126 | /// 127 | /// 128 | ///------------------------------------------------------------------------- 129 | /// 130 | /// **Example:** 131 | /// ~~~~~~~~~~~~~{.cpp} 132 | /// .. 133 | /// int wid = kodi::gui::GetCurrentWindowId() 134 | /// .. 135 | /// ~~~~~~~~~~~~~ 136 | /// 137 | inline int GetCurrentWindowId() 138 | { 139 | using namespace ::kodi::addon; 140 | return CAddonBase::m_interface->toKodi->kodi_gui->general->get_current_window_id(CAddonBase::m_interface->toKodi->kodiBase); 141 | } 142 | //-------------------------------------------------------------------------- 143 | 144 | } /* namespace gui */ 145 | } /* namespace kodi */ 146 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/Button.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../Window.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace controls 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_controls_CButton Control Button 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_class{ kodi::gui::controls::CButton } 26 | /// **Standard push button control for window** 27 | /// 28 | /// The button control is used for creating push buttons in Kodi. You can 29 | /// choose the position, size, and look of the button, as well as choosing 30 | /// what action(s) should be performed when pushed. 31 | /// 32 | /// It has the header \ref Button.h "#include " 33 | /// be included to enjoy it. 34 | /// 35 | /// Here you find the needed skin part for a \ref skin_Button_control "button control" 36 | /// 37 | /// @note The call of the control is only possible from the corresponding 38 | /// window as its class and identification number is required. 39 | /// 40 | class CButton : public CAddonGUIControlBase 41 | { 42 | public: 43 | //========================================================================== 44 | /// 45 | /// @ingroup cpp_kodi_gui_control_CButton 46 | /// @brief Construct a new control 47 | /// 48 | /// @param[in] window related window control class 49 | /// @param[in] controlId Used skin xml control id 50 | /// 51 | CButton(CWindow* window, int controlId) 52 | : CAddonGUIControlBase(window) 53 | { 54 | m_controlHandle = m_interface->kodi_gui->window->get_control_button(m_interface->kodiBase, m_Window->GetControlHandle(), controlId); 55 | if (!m_controlHandle) 56 | kodi::Log(ADDON_LOG_FATAL, "kodi::gui::CButton can't create control class from Kodi !!!"); 57 | } 58 | //-------------------------------------------------------------------------- 59 | 60 | //========================================================================== 61 | /// 62 | /// @ingroup cpp_kodi_gui_control_CButton 63 | /// @brief Destructor 64 | /// 65 | ~CButton() override = default; 66 | //-------------------------------------------------------------------------- 67 | 68 | //========================================================================== 69 | /// 70 | /// @ingroup cpp_kodi_gui_control_CButton 71 | /// @brief Set the control on window to visible 72 | /// 73 | /// @param[in] visible If true visible, otherwise hidden 74 | /// 75 | void SetVisible(bool visible) 76 | { 77 | m_interface->kodi_gui->control_button->set_visible(m_interface->kodiBase, m_controlHandle, visible); 78 | } 79 | //-------------------------------------------------------------------------- 80 | 81 | //========================================================================== 82 | /// 83 | /// @ingroup cpp_kodi_gui_control_CButton 84 | /// @brief Set's the control's enabled/disabled state 85 | /// 86 | /// @param[in] enabled If true enabled, otherwise disabled 87 | /// 88 | void SetEnabled(bool enabled) 89 | { 90 | m_interface->kodi_gui->control_button->set_enabled(m_interface->kodiBase, m_controlHandle, enabled); 91 | } 92 | //-------------------------------------------------------------------------- 93 | 94 | //========================================================================== 95 | /// 96 | /// @ingroup cpp_kodi_gui_control_CButton 97 | /// @brief To set the text string on button 98 | /// 99 | /// @param[in] label Text to show 100 | /// 101 | void SetLabel(const std::string& label) 102 | { 103 | m_interface->kodi_gui->control_button->set_label(m_interface->kodiBase, m_controlHandle, label.c_str()); 104 | } 105 | //-------------------------------------------------------------------------- 106 | 107 | //========================================================================== 108 | /// 109 | /// @ingroup cpp_kodi_gui_control_CButton 110 | /// @brief Get the used text from button 111 | /// 112 | /// @return Text shown 113 | /// 114 | std::string GetLabel() const 115 | { 116 | std::string label; 117 | char* ret = m_interface->kodi_gui->control_button->get_label(m_interface->kodiBase, m_controlHandle); 118 | if (ret != nullptr) 119 | { 120 | if (std::strlen(ret)) 121 | label = ret; 122 | m_interface->free_string(m_interface->kodiBase, ret); 123 | } 124 | return label; 125 | } 126 | //-------------------------------------------------------------------------- 127 | 128 | //========================================================================== 129 | /// 130 | /// @ingroup cpp_kodi_gui_control_CButton 131 | /// @brief If two labels are used for button becomes it set with them 132 | /// 133 | /// @param[in] label Text for second label 134 | /// 135 | void SetLabel2(const std::string& label) 136 | { 137 | m_interface->kodi_gui->control_button->set_label2(m_interface->kodiBase, m_controlHandle, label.c_str()); 138 | } 139 | //-------------------------------------------------------------------------- 140 | 141 | //========================================================================== 142 | /// 143 | /// @ingroup cpp_kodi_gui_control_CButton 144 | /// @brief Get the second label if present 145 | /// 146 | /// @return Second label 147 | /// 148 | std::string GetLabel2() const 149 | { 150 | std::string label; 151 | char* ret = m_interface->kodi_gui->control_button->get_label2(m_interface->kodiBase, m_controlHandle); 152 | if (ret != nullptr) 153 | { 154 | if (std::strlen(ret)) 155 | label = ret; 156 | m_interface->free_string(m_interface->kodiBase, ret); 157 | } 158 | return label; 159 | } 160 | //-------------------------------------------------------------------------- 161 | }; 162 | 163 | } /* namespace controls */ 164 | } /* namespace gui */ 165 | } /* namespace kodi */ 166 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(HEADERS Button.h 2 | Edit.h 3 | FadeLabel.h 4 | Image.h 5 | Label.h 6 | Progress.h 7 | RadioButton.h 8 | Rendering.h 9 | SettingsSlider.h 10 | Slider.h 11 | Spin.h 12 | TextBox.h) 13 | 14 | if(NOT ENABLE_STATIC_LIBS) 15 | core_add_library(addons_kodi-addon-dev-kit_include_kodi_gui_controls) 16 | endif() 17 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/FadeLabel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../Window.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace controls 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_controls_CFadeLabel Control Fade Label 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_class{ kodi::gui::controls::CFadeLabel } 26 | /// **Window control used to show multiple pieces of text in the same position, 27 | /// by fading from one to the other** 28 | /// 29 | /// The fade label control is used for displaying multiple pieces of text in 30 | /// the same space in Kodi. You can choose the font, size, colour, location 31 | /// and contents of the text to be displayed. The first piece of information 32 | /// to display fades in over 50 frames, then scrolls off to the left. Once it 33 | /// is finished scrolling off screen, the second piece of information fades 34 | /// in and the process repeats. A fade label control is not supported in a 35 | /// list container. 36 | /// 37 | /// It has the header \ref FadeLabel.h "#include " 38 | /// be included to enjoy it. 39 | /// 40 | /// Here you find the needed skin part for a \ref Fade_Label_Control "fade label control" 41 | /// 42 | /// @note The call of the control is only possible from the corresponding 43 | /// window as its class and identification number is required. 44 | /// 45 | class CFadeLabel : public CAddonGUIControlBase 46 | { 47 | public: 48 | //========================================================================== 49 | /// 50 | /// \ingroup cpp_kodi_gui_controls_CFadeLabel 51 | /// @brief Construct a new control. 52 | /// 53 | /// @param[in] window related window control class 54 | /// @param[in] controlId Used skin xml control id 55 | /// 56 | CFadeLabel(CWindow* window, int controlId) 57 | : CAddonGUIControlBase(window) 58 | { 59 | m_controlHandle = m_interface->kodi_gui->window->get_control_fade_label(m_interface->kodiBase, m_Window->GetControlHandle(), controlId); 60 | if (!m_controlHandle) 61 | kodi::Log(ADDON_LOG_FATAL, "kodi::gui::controls::CFadeLabel can't create control class from Kodi !!!"); 62 | } 63 | //-------------------------------------------------------------------------- 64 | 65 | //========================================================================== 66 | /// 67 | /// \ingroup cpp_kodi_gui_controls_CFadeLabel 68 | /// @brief Destructor. 69 | /// 70 | ~CFadeLabel() override = default; 71 | //-------------------------------------------------------------------------- 72 | 73 | //========================================================================== 74 | /// 75 | /// \ingroup cpp_kodi_gui_controls_CFadeLabel 76 | /// @brief Set the control on window to visible. 77 | /// 78 | /// @param[in] visible If true visible, otherwise hidden 79 | /// 80 | void SetVisible(bool visible) 81 | { 82 | m_interface->kodi_gui->control_fade_label->set_visible(m_interface->kodiBase, m_controlHandle, visible); 83 | } 84 | //-------------------------------------------------------------------------- 85 | 86 | //========================================================================== 87 | /// 88 | /// \ingroup cpp_kodi_gui_controls_CFadeLabel 89 | /// @brief To add additional text string on fade label. 90 | /// 91 | /// @param[in] label Text to show 92 | /// 93 | void AddLabel(const std::string& label) 94 | { 95 | m_interface->kodi_gui->control_fade_label->add_label(m_interface->kodiBase, m_controlHandle, label.c_str()); 96 | } 97 | //-------------------------------------------------------------------------- 98 | 99 | //========================================================================== 100 | /// 101 | /// \ingroup cpp_kodi_gui_controls_CFadeLabel 102 | /// @brief Get the used text from button 103 | /// 104 | /// @return Text shown 105 | /// 106 | std::string GetLabel() const 107 | { 108 | std::string label; 109 | char* ret = m_interface->kodi_gui->control_fade_label->get_label(m_interface->kodiBase, m_controlHandle); 110 | if (ret != nullptr) 111 | { 112 | if (std::strlen(ret)) 113 | label = ret; 114 | m_interface->free_string(m_interface->kodiBase, ret); 115 | } 116 | return label; 117 | } 118 | //-------------------------------------------------------------------------- 119 | 120 | //========================================================================== 121 | /// 122 | /// \ingroup cpp_kodi_gui_controls_CFadeLabel 123 | /// @brief To enable or disable scrolling on fade label 124 | /// 125 | /// @param[in] scroll To enable scrolling set to true, otherwise is 126 | /// disabled 127 | /// 128 | void SetScrolling(bool scroll) 129 | { 130 | m_interface->kodi_gui->control_fade_label->set_scrolling(m_interface->kodiBase, m_controlHandle, scroll); 131 | } 132 | //-------------------------------------------------------------------------- 133 | 134 | //========================================================================== 135 | /// 136 | /// \ingroup cpp_kodi_gui_controls_CFadeLabel 137 | /// @brief To reset al inserted labels. 138 | /// 139 | void Reset() 140 | { 141 | m_interface->kodi_gui->control_fade_label->reset(m_interface->kodiBase, m_controlHandle); 142 | } 143 | //-------------------------------------------------------------------------- 144 | }; 145 | 146 | } /* namespace controls */ 147 | } /* namespace gui */ 148 | } /* namespace kodi */ 149 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/Image.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../Window.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace controls 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_controls_CImage Control Image 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_class{ kodi::gui::controls::CImage } 26 | /// **Window control used to show an image.** 27 | /// 28 | /// The image control is used for displaying images in Kodi. You can choose 29 | /// the position, size, transparency and contents of the image to be displayed. 30 | /// 31 | /// It has the header \ref Image.h "#include " 32 | /// be included to enjoy it. 33 | /// 34 | /// Here you find the needed skin part for a \ref Image_Control "image control" 35 | /// 36 | /// @note The call of the control is only possible from the corresponding 37 | /// window as its class and identification number is required. 38 | /// 39 | class CImage : public CAddonGUIControlBase 40 | { 41 | public: 42 | //========================================================================== 43 | /// 44 | /// \ingroup cpp_kodi_gui_controls_CImage 45 | /// @brief Construct a new control 46 | /// 47 | /// @param[in] window related window control class 48 | /// @param[in] controlId Used skin xml control id 49 | /// 50 | CImage(CWindow* window, int controlId) 51 | : CAddonGUIControlBase(window) 52 | { 53 | m_controlHandle = m_interface->kodi_gui->window->get_control_image(m_interface->kodiBase, m_Window->GetControlHandle(), controlId); 54 | if (!m_controlHandle) 55 | kodi::Log(ADDON_LOG_FATAL, "kodi::gui::controls::CImage can't create control class from Kodi !!!"); 56 | } 57 | //-------------------------------------------------------------------------- 58 | 59 | //========================================================================== 60 | /// 61 | /// \ingroup cpp_kodi_gui_controls_CImage 62 | /// @brief Destructor 63 | /// 64 | ~CImage() override = default; 65 | //-------------------------------------------------------------------------- 66 | 67 | //========================================================================== 68 | /// 69 | /// \ingroup cpp_kodi_gui_controls_CImage 70 | /// @brief Set the control on window to visible 71 | /// 72 | /// @param[in] visible If true visible, otherwise hidden 73 | /// 74 | void SetVisible(bool visible) 75 | { 76 | m_interface->kodi_gui->control_image->set_visible(m_interface->kodiBase, m_controlHandle, visible); 77 | } 78 | //-------------------------------------------------------------------------- 79 | 80 | //========================================================================== 81 | /// 82 | /// \ingroup cpp_kodi_gui_controls_CImage 83 | /// @brief To set the filename used on image control. 84 | /// 85 | /// @param[in] filename Image file to use 86 | /// @param[in] useCache To define storage of image, default is 87 | /// in cache, if false becomes it loaded 88 | /// always on changes again 89 | /// 90 | void SetFileName(const std::string& filename, bool useCache = true) 91 | { 92 | m_interface->kodi_gui->control_image->set_filename(m_interface->kodiBase, m_controlHandle, filename.c_str(), useCache); 93 | } 94 | //-------------------------------------------------------------------------- 95 | 96 | //========================================================================== 97 | /// 98 | /// \ingroup cpp_kodi_gui_controls_CImage 99 | /// @brief To set set the diffuse color on image. 100 | /// 101 | /// @param[in] colorDiffuse Color to use for diffuse 102 | /// 103 | void SetColorDiffuse(uint32_t colorDiffuse) 104 | { 105 | m_interface->kodi_gui->control_image->set_color_diffuse(m_interface->kodiBase, m_controlHandle, colorDiffuse); 106 | } 107 | //-------------------------------------------------------------------------- 108 | }; 109 | 110 | } /* namespace controls */ 111 | } /* namespace gui */ 112 | } /* namespace kodi */ 113 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/Label.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../Window.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace controls 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_controls_CLabel Control Label 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_class{ kodi::gui::controls::CLabel } 26 | /// **Window control used to show some lines of text.** 27 | /// 28 | /// The label control is used for displaying text in Kodi. You can choose 29 | /// the font, size, colour, location and contents of the text to be displayed. 30 | /// 31 | /// It has the header \ref Label.h "#include " 32 | /// be included to enjoy it. 33 | /// 34 | /// Here you find the needed skin part for a \ref Label_Control "label control" 35 | /// 36 | /// @note The call of the control is only possible from the corresponding 37 | /// window as its class and identification number is required. 38 | /// 39 | class CLabel : public CAddonGUIControlBase 40 | { 41 | public: 42 | //========================================================================== 43 | /// 44 | /// \ingroup cpp_kodi_gui_controls_CLabel 45 | /// @brief Construct a new control 46 | /// 47 | /// @param[in] window related window control class 48 | /// @param[in] controlId Used skin xml control id 49 | /// 50 | CLabel(CWindow* window, int controlId) 51 | : CAddonGUIControlBase(window) 52 | { 53 | m_controlHandle = m_interface->kodi_gui->window->get_control_label(m_interface->kodiBase, m_Window->GetControlHandle(), controlId); 54 | if (!m_controlHandle) 55 | kodi::Log(ADDON_LOG_FATAL, "kodi::gui::controls::CLabel can't create control class from Kodi !!!"); 56 | } 57 | //-------------------------------------------------------------------------- 58 | 59 | //========================================================================== 60 | /// 61 | /// \ingroup cpp_kodi_gui_controls_CLabel 62 | /// @brief Destructor 63 | /// 64 | ~CLabel() override = default; 65 | //-------------------------------------------------------------------------- 66 | 67 | //========================================================================== 68 | /// 69 | /// \ingroup cpp_kodi_gui_controls_CLabel 70 | /// @brief Set the control on window to visible 71 | /// 72 | /// @param[in] visible If true visible, otherwise hidden 73 | /// 74 | void SetVisible(bool visible) 75 | { 76 | m_interface->kodi_gui->control_label->set_visible(m_interface->kodiBase, m_controlHandle, visible); 77 | } 78 | //-------------------------------------------------------------------------- 79 | 80 | //========================================================================== 81 | /// 82 | /// \ingroup cpp_kodi_gui_controls_CLabel 83 | /// @brief To set the text string on label 84 | /// 85 | /// @param[in] text Text to show 86 | /// 87 | void SetLabel(const std::string& text) 88 | { 89 | m_interface->kodi_gui->control_label->set_label(m_interface->kodiBase, m_controlHandle, text.c_str()); 90 | } 91 | //-------------------------------------------------------------------------- 92 | 93 | //========================================================================== 94 | /// 95 | /// \ingroup cpp_kodi_gui_controls_CLabel 96 | /// @brief Get the used text from control 97 | /// 98 | /// @return Used text on label control 99 | /// 100 | std::string GetLabel() const 101 | { 102 | std::string label; 103 | char* ret = m_interface->kodi_gui->control_label->get_label(m_interface->kodiBase, m_controlHandle); 104 | if (ret != nullptr) 105 | { 106 | if (std::strlen(ret)) 107 | label = ret; 108 | m_interface->free_string(m_interface->kodiBase, ret); 109 | } 110 | return label; 111 | } 112 | //-------------------------------------------------------------------------- 113 | }; 114 | 115 | } /* namespace controls */ 116 | } /* namespace gui */ 117 | } /* namespace kodi */ 118 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/Progress.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../Window.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace controls 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_controls_CProgress Control Progress 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_class{ kodi::gui::controls::CProgress } 26 | /// **Window control to show the progress of a particular operation** 27 | /// 28 | /// The progress control is used to show the progress of an item that may take 29 | /// a long time, or to show how far through a movie you are. You can choose 30 | /// the position, size, and look of the progress control. 31 | /// 32 | /// It has the header \ref Progress.h "#include " 33 | /// be included to enjoy it. 34 | /// 35 | /// Here you find the needed skin part for a \ref Progress_Control "progress control" 36 | /// 37 | /// @note The call of the control is only possible from the corresponding 38 | /// window as its class and identification number is required. 39 | /// 40 | class CProgress : public CAddonGUIControlBase 41 | { 42 | public: 43 | //========================================================================== 44 | /// 45 | /// \ingroup cpp_kodi_gui_controls_CProgress 46 | /// @brief Construct a new control 47 | /// 48 | /// @param[in] window related window control class 49 | /// @param[in] controlId Used skin xml control id 50 | /// 51 | CProgress(CWindow* window, int controlId) 52 | : CAddonGUIControlBase(window) 53 | { 54 | m_controlHandle = m_interface->kodi_gui->window->get_control_progress(m_interface->kodiBase, m_Window->GetControlHandle(), controlId); 55 | if (!m_controlHandle) 56 | kodi::Log(ADDON_LOG_FATAL, "kodi::gui::controls::CProgress can't create control class from Kodi !!!"); 57 | } 58 | //-------------------------------------------------------------------------- 59 | 60 | //========================================================================== 61 | /// 62 | /// \ingroup cpp_kodi_gui_controls_CProgress 63 | /// @brief Destructor 64 | /// 65 | ~CProgress() override = default; 66 | //-------------------------------------------------------------------------- 67 | 68 | //========================================================================== 69 | /// 70 | /// \ingroup cpp_kodi_gui_controls_CProgress 71 | /// @brief Set the control on window to visible 72 | /// 73 | /// @param[in] visible If true visible, otherwise hidden 74 | /// 75 | void SetVisible(bool visible) 76 | { 77 | m_interface->kodi_gui->control_progress->set_visible(m_interface->kodiBase, m_controlHandle, visible); 78 | } 79 | //-------------------------------------------------------------------------- 80 | 81 | //========================================================================== 82 | /// 83 | /// \ingroup cpp_kodi_gui_controls_CProgress 84 | /// @brief To set Percent position of control 85 | /// 86 | /// @param[in] percent The percent position to use 87 | /// 88 | void SetPercentage(float percent) 89 | { 90 | m_interface->kodi_gui->control_progress->set_percentage(m_interface->kodiBase, m_controlHandle, percent); 91 | } 92 | //-------------------------------------------------------------------------- 93 | 94 | //========================================================================== 95 | /// 96 | /// \ingroup cpp_kodi_gui_controls_CProgress 97 | /// @brief Get the active percent position of progress bar 98 | /// 99 | /// @return Progress position as percent 100 | /// 101 | float GetPercentage() const 102 | { 103 | return m_interface->kodi_gui->control_progress->get_percentage(m_interface->kodiBase, m_controlHandle); 104 | } 105 | //-------------------------------------------------------------------------- 106 | }; 107 | 108 | } /* namespace controls */ 109 | } /* namespace gui */ 110 | } /* namespace kodi */ 111 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/RadioButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../Window.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace controls 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_controls_CRadioButton Control Radio Button 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_class{ kodi::gui::controls::CRadioButton } 26 | /// **Window control for a radio button (as used for on/off settings)** 27 | /// 28 | /// The radio button control is used for creating push button on/off settings 29 | /// in Kodi. You can choose the position, size, and look of the button. When 30 | /// the user clicks on the radio button, the state will change, toggling the 31 | /// extra textures (textureradioon and textureradiooff). Used for settings 32 | /// controls. 33 | /// 34 | /// It has the header \ref RadioButton.h "#include " 35 | /// be included to enjoy it. 36 | /// 37 | /// Here you find the needed skin part for a \ref Radio_button_control "radio button control" 38 | /// 39 | /// @note The call of the control is only possible from the corresponding 40 | /// window as its class and identification number is required. 41 | /// 42 | class CRadioButton : public CAddonGUIControlBase 43 | { 44 | public: 45 | //========================================================================== 46 | /// 47 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 48 | /// @brief Construct a new control 49 | /// 50 | /// @param[in] window related window control class 51 | /// @param[in] controlId Used skin xml control id 52 | /// 53 | CRadioButton(CWindow* window, int controlId) 54 | : CAddonGUIControlBase(window) 55 | { 56 | m_controlHandle = m_interface->kodi_gui->window->get_control_radio_button(m_interface->kodiBase, m_Window->GetControlHandle(), controlId); 57 | if (!m_controlHandle) 58 | kodi::Log(ADDON_LOG_FATAL, "kodi::gui::controls::CRadioButton can't create control class from Kodi !!!"); 59 | } 60 | //-------------------------------------------------------------------------- 61 | 62 | //========================================================================== 63 | /// 64 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 65 | /// @brief Destructor 66 | /// 67 | ~CRadioButton() override = default; 68 | //-------------------------------------------------------------------------- 69 | 70 | //========================================================================== 71 | /// 72 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 73 | /// @brief Set the control on window to visible 74 | /// 75 | /// @param[in] visible If true visible, otherwise hidden 76 | /// 77 | void SetVisible(bool visible) 78 | { 79 | m_interface->kodi_gui->control_radio_button->set_visible(m_interface->kodiBase, m_controlHandle, visible); 80 | } 81 | //-------------------------------------------------------------------------- 82 | 83 | //========================================================================== 84 | /// 85 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 86 | /// @brief Set's the control's enabled/disabled state 87 | /// 88 | /// @param[in] enabled If true enabled, otherwise disabled 89 | /// 90 | void SetEnabled(bool enabled) 91 | { 92 | m_interface->kodi_gui->control_radio_button->set_enabled(m_interface->kodiBase, m_controlHandle, enabled); 93 | } 94 | //-------------------------------------------------------------------------- 95 | 96 | //========================================================================== 97 | /// 98 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 99 | /// @brief To set the text string on radio button 100 | /// 101 | /// @param[in] label Text to show 102 | /// 103 | void SetLabel(const std::string& label) 104 | { 105 | m_interface->kodi_gui->control_radio_button->set_label(m_interface->kodiBase, m_controlHandle, label.c_str()); 106 | } 107 | //-------------------------------------------------------------------------- 108 | 109 | //========================================================================== 110 | /// 111 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 112 | /// @brief Get the used text from control 113 | /// 114 | /// @return Text shown 115 | /// 116 | std::string GetLabel() const 117 | { 118 | std::string label; 119 | char* ret = m_interface->kodi_gui->control_radio_button->get_label(m_interface->kodiBase, m_controlHandle); 120 | if (ret != nullptr) 121 | { 122 | if (std::strlen(ret)) 123 | label = ret; 124 | m_interface->free_string(m_interface->kodiBase, ret); 125 | } 126 | return label; 127 | } 128 | //-------------------------------------------------------------------------- 129 | 130 | //========================================================================== 131 | /// 132 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 133 | /// @brief To set radio button condition to on or off 134 | /// 135 | /// @param[in] selected true set radio button to selection on, otherwise 136 | /// off 137 | /// 138 | void SetSelected(bool selected) 139 | { 140 | m_interface->kodi_gui->control_radio_button->set_selected(m_interface->kodiBase, m_controlHandle, selected); 141 | } 142 | //-------------------------------------------------------------------------- 143 | 144 | //========================================================================== 145 | /// 146 | /// \ingroup cpp_kodi_gui_controls_CRadioButton 147 | /// @brief Get the current selected condition of radio button 148 | /// 149 | /// @return Selected condition 150 | /// 151 | bool IsSelected() const 152 | { 153 | return m_interface->kodi_gui->control_radio_button->is_selected(m_interface->kodiBase, m_controlHandle); 154 | } 155 | //-------------------------------------------------------------------------- 156 | }; 157 | 158 | } /* namespace controls */ 159 | } /* namespace gui */ 160 | } /* namespace kodi */ 161 | -------------------------------------------------------------------------------- /include/kodi/gui/controls/TextBox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../Window.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace controls 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_controls_CTextBox Control Text Box 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_class{ kodi::gui::controls::CTextBox } 26 | /// **Used to show a multi-page piece of text** 27 | /// 28 | /// The text box control can be used to display descriptions, help texts or 29 | /// other larger texts. It corresponds to the representation which is also to 30 | /// be seen on the CDialogTextViewer. 31 | /// 32 | /// It has the header \ref TextBox.h "#include " 33 | /// be included to enjoy it. 34 | /// 35 | /// Here you find the needed skin part for a \ref Text_Box "textbox control". 36 | /// 37 | /// @note The call of the control is only possible from the corresponding 38 | /// window as its class and identification number is required. 39 | /// 40 | class CTextBox : public CAddonGUIControlBase 41 | { 42 | public: 43 | //========================================================================== 44 | /// 45 | /// \ingroup cpp_kodi_gui_controls_CTextBox 46 | /// @brief Construct a new control 47 | /// 48 | /// @param[in] window related window control class 49 | /// @param[in] controlId Used skin xml control id 50 | /// 51 | CTextBox(CWindow* window, int controlId) 52 | : CAddonGUIControlBase(window) 53 | { 54 | m_controlHandle = m_interface->kodi_gui->window->get_control_text_box(m_interface->kodiBase, m_Window->GetControlHandle(), controlId); 55 | if (!m_controlHandle) 56 | kodi::Log(ADDON_LOG_FATAL, "kodi::gui::controls::CTextBox can't create control class from Kodi !!!"); 57 | } 58 | //-------------------------------------------------------------------------- 59 | 60 | //========================================================================== 61 | /// 62 | /// \ingroup cpp_kodi_gui_controls_CTextBox 63 | /// @brief Destructor 64 | /// 65 | ~CTextBox() override = default; 66 | //-------------------------------------------------------------------------- 67 | 68 | //========================================================================== 69 | /// 70 | /// \ingroup cpp_kodi_gui_controls_CTextBox 71 | /// @brief Set the control on window to visible 72 | /// 73 | /// @param[in] visible If true visible, otherwise hidden 74 | /// 75 | void SetVisible(bool visible) 76 | { 77 | m_interface->kodi_gui->control_text_box->set_visible(m_interface->kodiBase, m_controlHandle, visible); 78 | } 79 | //-------------------------------------------------------------------------- 80 | 81 | //========================================================================== 82 | /// 83 | /// \ingroup cpp_kodi_gui_controls_CTextBox 84 | /// @brief To reset box an remove all the text 85 | /// 86 | void Reset() 87 | { 88 | m_interface->kodi_gui->control_text_box->reset(m_controlHandle, m_controlHandle); 89 | } 90 | //-------------------------------------------------------------------------- 91 | 92 | //========================================================================== 93 | /// 94 | /// \ingroup cpp_kodi_gui_controls_CTextBox 95 | /// @brief To set the text on box 96 | /// 97 | /// @param[in] text Text to show 98 | /// 99 | void SetText(const std::string& text) 100 | { 101 | m_interface->kodi_gui->control_text_box->set_text(m_interface->kodiBase, m_controlHandle, text.c_str()); 102 | } 103 | //-------------------------------------------------------------------------- 104 | 105 | //========================================================================== 106 | /// 107 | /// \ingroup cpp_kodi_gui_controls_CTextBox 108 | /// @brief Get the used text from control 109 | /// 110 | /// @return Text shown 111 | /// 112 | std::string GetText() const 113 | { 114 | std::string text; 115 | char* ret = m_interface->kodi_gui->control_text_box->get_text(m_interface->kodiBase, m_controlHandle); 116 | if (ret != nullptr) 117 | { 118 | if (std::strlen(ret)) 119 | text = ret; 120 | m_interface->free_string(m_interface->kodiBase, ret); 121 | } 122 | return text; 123 | } 124 | //-------------------------------------------------------------------------- 125 | 126 | //========================================================================== 127 | /// 128 | /// \ingroup cpp_kodi_gui_controls_CTextBox 129 | /// @brief To scroll text on other position 130 | /// 131 | /// @param[in] position The line position to scroll to 132 | /// 133 | void Scroll(unsigned int position) 134 | { 135 | m_interface->kodi_gui->control_text_box->scroll(m_interface->kodiBase, m_controlHandle, position); 136 | } 137 | //-------------------------------------------------------------------------- 138 | 139 | //========================================================================== 140 | /// 141 | /// \ingroup cpp_kodi_gui_controls_CTextBox 142 | /// @brief To set automatic scrolling of textbox 143 | /// 144 | /// Specifies the timing and conditions of any autoscrolling this textbox 145 | /// should have. Times are in milliseconds. The content is delayed for the 146 | /// given delay, then scrolls at a rate of one line per time interval until 147 | /// the end. If the repeat tag is present, it then delays for the repeat 148 | /// time, fades out over 1 second, and repeats. It does not wrap or reset 149 | /// to the top at the end of the scroll. 150 | /// 151 | /// @param[in] delay Content delay 152 | /// @param[in] time One line per time interval 153 | /// @param[in] repeat Delays with given time, fades out over 1 154 | /// second, and repeats 155 | /// 156 | void SetAutoScrolling(int delay, int time, int repeat) 157 | { 158 | m_interface->kodi_gui->control_text_box->set_auto_scrolling(m_interface->kodiBase, m_controlHandle, delay, time, repeat); 159 | } 160 | //-------------------------------------------------------------------------- 161 | }; 162 | 163 | } /* namespace controls */ 164 | } /* namespace gui */ 165 | } /* namespace kodi */ 166 | -------------------------------------------------------------------------------- /include/kodi/gui/dialogs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(HEADERS ContextMenu.h 2 | ExtendedProgress.h 3 | FileBrowser.h 4 | Keyboard.h 5 | Numeric.h 6 | OK.h 7 | Progress.h 8 | Select.h 9 | TextViewer.h 10 | YesNo.h) 11 | 12 | if(NOT ENABLE_STATIC_LIBS) 13 | core_add_library(addons_kodi-addon-dev-kit_include_kodi_gui_dialogs) 14 | endif() 15 | -------------------------------------------------------------------------------- /include/kodi/gui/dialogs/ContextMenu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../definitions.h" 12 | #include "../../AddonBase.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace dialogs 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_dialogs_ContextMenu Dialog Context Menu 24 | /// \ingroup cpp_kodi_gui 25 | /// @brief \cpp_namespace{ kodi::gui::dialogs::ContextMenu } 26 | /// **Context menu dialog** 27 | /// 28 | /// The function listed below permits the call of a dialogue as context menu to 29 | /// select of an entry as a key 30 | /// 31 | /// It has the header \ref ContextMenu.h "#include " 32 | /// be included to enjoy it. 33 | /// 34 | /// 35 | namespace ContextMenu 36 | { 37 | //========================================================================== 38 | /// 39 | /// \ingroup cpp_kodi_gui_dialogs_ContextMenu 40 | /// @brief Show a context menu dialog about given parts. 41 | /// 42 | /// @param[in] heading Dialog heading name 43 | /// @param[in] entries String list about entries 44 | /// @return The selected entry, if return -1 was nothing selected or canceled 45 | /// 46 | /// 47 | ///------------------------------------------------------------------------- 48 | /// 49 | /// **Example:** 50 | /// ~~~~~~~~~~~~~{.cpp} 51 | /// #include 52 | /// 53 | /// const std::vector entries 54 | /// { 55 | /// "Test 1", 56 | /// "Test 2", 57 | /// "Test 3", 58 | /// "Test 4", 59 | /// "Test 5" 60 | /// }; 61 | /// 62 | /// int selected = kodi::gui::dialogs::ContextMenu::Show("Test selection", entries); 63 | /// if (selected < 0) 64 | /// fprintf(stderr, "Item selection canceled\n"); 65 | /// else 66 | /// fprintf(stderr, "Selected item is: %i\n", selected); 67 | /// ~~~~~~~~~~~~~ 68 | /// 69 | inline int Show(const std::string& heading, const std::vector& entries) 70 | { 71 | using namespace ::kodi::addon; 72 | unsigned int size = entries.size(); 73 | const char** cEntries = static_cast(malloc(size*sizeof(const char**))); 74 | for (unsigned int i = 0; i < size; ++i) 75 | { 76 | cEntries[i] = entries[i].c_str(); 77 | } 78 | int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size); 79 | free(cEntries); 80 | return ret; 81 | } 82 | //-------------------------------------------------------------------------- 83 | 84 | //========================================================================== 85 | /// 86 | /// \ingroup cpp_kodi_gui_dialogs_ContextMenu 87 | /// @brief Show a context menu dialog about given parts. 88 | /// 89 | /// @param[in] heading Dialog heading name 90 | /// @param[in] entries String list about entries 91 | /// @return The selected entry, if return -1 was nothing selected or canceled 92 | /// 93 | /// 94 | ///------------------------------------------------------------------------- 95 | /// 96 | /// **Example:** 97 | /// ~~~~~~~~~~~~~{.cpp} 98 | /// #include 99 | /// 100 | /// const std::vector> entries 101 | /// { 102 | /// { "ID 1", "Test 1" }, 103 | /// { "ID 2", "Test 2" }, 104 | /// { "ID 3", "Test 3" }, 105 | /// { "ID 4", "Test 4" }, 106 | /// { "ID 5", "Test 5" } 107 | /// }; 108 | /// 109 | /// int selected = kodi::gui::dialogs::ContextMenu::Show("Test selection", entries); 110 | /// if (selected < 0) 111 | /// fprintf(stderr, "Item selection canceled\n"); 112 | /// else 113 | /// fprintf(stderr, "Selected item is: %i\n", selected); 114 | /// ~~~~~~~~~~~~~ 115 | /// 116 | inline int Show(const std::string& heading, const std::vector>& entries) 117 | { 118 | using namespace ::kodi::addon; 119 | unsigned int size = entries.size(); 120 | const char** cEntries = static_cast(malloc(size*sizeof(const char**))); 121 | for (unsigned int i = 0; i < size; ++i) 122 | { 123 | cEntries[i] = entries[i].second.c_str(); 124 | } 125 | int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size); 126 | free(cEntries); 127 | return ret; 128 | } 129 | //-------------------------------------------------------------------------- 130 | 131 | //========================================================================== 132 | /// 133 | /// \ingroup cpp_kodi_gui_dialogs_ContextMenu 134 | /// @brief Show a context menu dialog about given parts. 135 | /// 136 | /// @param[in] heading Dialog heading name 137 | /// @param[in] entries String list about entries 138 | /// @return The selected entry, if return -1 was nothing selected or canceled 139 | /// 140 | /// 141 | ///------------------------------------------------------------------------- 142 | /// 143 | /// **Example:** 144 | /// ~~~~~~~~~~~~~{.cpp} 145 | /// #include 146 | /// 147 | /// const std::vector> entries 148 | /// { 149 | /// { 1, "Test 1" }, 150 | /// { 2, "Test 2" }, 151 | /// { 3, "Test 3" }, 152 | /// { 4, "Test 4" }, 153 | /// { 5, "Test 5" } 154 | /// }; 155 | /// 156 | /// int selected = kodi::gui::dialogs::ContextMenu::Show("Test selection", entries); 157 | /// if (selected < 0) 158 | /// fprintf(stderr, "Item selection canceled\n"); 159 | /// else 160 | /// fprintf(stderr, "Selected item is: %i\n", selected); 161 | /// ~~~~~~~~~~~~~ 162 | /// 163 | inline int Show(const std::string& heading, const std::vector>& entries) 164 | { 165 | using namespace ::kodi::addon; 166 | unsigned int size = entries.size(); 167 | const char** cEntries = static_cast(malloc(size*sizeof(const char**))); 168 | for (unsigned int i = 0; i < size; ++i) 169 | { 170 | cEntries[i] = entries[i].second.c_str(); 171 | } 172 | int ret = CAddonBase::m_interface->toKodi->kodi_gui->dialogContextMenu->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), cEntries, size); 173 | free(cEntries); 174 | return ret; 175 | } 176 | //-------------------------------------------------------------------------- 177 | }; 178 | 179 | } /* namespace dialogs */ 180 | } /* namespace gui */ 181 | } /* namespace kodi */ 182 | -------------------------------------------------------------------------------- /include/kodi/gui/dialogs/OK.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | #include "../definitions.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace dialogs 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_dialogs_OK Dialog OK 24 | /// \ingroup cpp_kodi_gui 25 | /// @{ 26 | /// @brief \cpp_namespace{ kodi::gui::dialogs::OK } 27 | /// **OK dialog** 28 | /// 29 | /// The functions listed below permit the call of a dialogue of information, a 30 | /// confirmation of the user by press from OK required. 31 | /// 32 | /// It has the header \ref OK.h "#include " 33 | /// be included to enjoy it. 34 | /// 35 | namespace OK 36 | { 37 | //========================================================================== 38 | /// 39 | /// \ingroup cpp_kodi_gui_dialogs_OK 40 | /// @brief Use dialog to inform user with text and confirmation with OK with continued string. 41 | /// 42 | /// @param[in] heading Dialog heading. 43 | /// @param[in] text Multi-line text. 44 | /// 45 | /// 46 | ///------------------------------------------------------------------------- 47 | /// 48 | /// **Example:** 49 | /// ~~~~~~~~~~~~~{.cpp} 50 | /// #include 51 | /// ... 52 | /// kodi::gui::dialogs::OK::ShowAndGetInput("Test dialog", "Hello World!\nI'm a call from add-on\n :) :D"); 53 | /// ~~~~~~~~~~~~~ 54 | /// 55 | inline void ShowAndGetInput(const std::string& heading, const std::string& text) 56 | { 57 | using namespace ::kodi::addon; 58 | CAddonBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_single_text(CAddonBase::m_interface->toKodi->kodiBase, 59 | heading.c_str(), text.c_str()); 60 | } 61 | //-------------------------------------------------------------------------- 62 | 63 | //========================================================================== 64 | /// 65 | /// \ingroup cpp_kodi_gui_dialogs_OK 66 | /// @brief Use dialog to inform user with text and confirmation with OK with strings separated to the lines. 67 | /// 68 | /// @param[in] heading Dialog heading. 69 | /// @param[in] line0 Line #1 text. 70 | /// @param[in] line1 Line #2 text. 71 | /// @param[in] line2 Line #3 text. 72 | /// 73 | /// 74 | ///------------------------------------------------------------------------- 75 | /// 76 | /// **Example:** 77 | /// ~~~~~~~~~~~~~{.cpp} 78 | /// #include 79 | /// ... 80 | /// kodi::gui::dialogs::OK::ShowAndGetInput("Test dialog", "Hello World!", "I'm a call from add-on", " :) :D"); 81 | /// ~~~~~~~~~~~~~ 82 | /// 83 | inline void ShowAndGetInput(const std::string& heading, const std::string& line0, const std::string& line1, const std::string& line2) 84 | { 85 | using namespace ::kodi::addon; 86 | CAddonBase::m_interface->toKodi->kodi_gui->dialogOK->show_and_get_input_line_text(CAddonBase::m_interface->toKodi->kodiBase, 87 | heading.c_str(), line0.c_str(), line1.c_str(), 88 | line2.c_str()); 89 | } 90 | //-------------------------------------------------------------------------- 91 | } 92 | /// @} 93 | 94 | } /* namespace dialogs */ 95 | } /* namespace gui */ 96 | } /* namespace kodi */ 97 | -------------------------------------------------------------------------------- /include/kodi/gui/dialogs/TextViewer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../definitions.h" 12 | #include "../../AddonBase.h" 13 | 14 | namespace kodi 15 | { 16 | namespace gui 17 | { 18 | namespace dialogs 19 | { 20 | 21 | //============================================================================ 22 | /// 23 | /// \defgroup cpp_kodi_gui_dialogs_TextViewer Dialog Text Viewer 24 | /// \ingroup cpp_kodi_gui 25 | /// @{ 26 | /// @brief \cpp_namespace{ kodi::gui::dialogs::TextViewer } 27 | /// **Text viewer dialog** 28 | /// 29 | /// The text viewer dialog can be used to display descriptions, help texts or 30 | /// other larger texts. 31 | /// 32 | /// In order to achieve a line break is a \\n directly in the text or 33 | /// in the "./resources/language/resource.language.??_??/strings.po" 34 | /// to call with std::string kodi::general::GetLocalizedString(...);. 35 | /// 36 | /// It has the header \ref TextViewer.h "#include " 37 | /// be included to enjoy it. 38 | /// 39 | namespace TextViewer 40 | { 41 | //========================================================================== 42 | /// 43 | /// \ingroup cpp_kodi_gui_dialogs_TextViewer 44 | /// @brief Show info text dialog 45 | /// 46 | /// @param[in] heading Small heading text 47 | /// @param[in] text Showed text on dialog 48 | /// 49 | /// 50 | ///------------------------------------------------------------------------- 51 | /// 52 | /// **Example:** 53 | /// ~~~~~~~~~~~~~{.cpp} 54 | /// #include 55 | /// 56 | /// kodi::gui::dialogs::TextViewer::Show("The Wizard of Oz (1939 film)", 57 | /// "The Wizard of Oz is a 1939 American musical comedy-drama fantasy film " 58 | /// "produced by Metro-Goldwyn-Mayer, and the most well-known and commercially " 59 | /// "successful adaptation based on the 1900 novel The Wonderful Wizard of Oz " 60 | /// "by L. Frank Baum. The film stars Judy Garland as Dorothy Gale. The film" 61 | /// "co-stars Terry the dog, billed as Toto; Ray Bolger, Jack Haley, Bert Lahr, " 62 | /// "Frank Morgan, Billie Burke, Margaret Hamilton, with Charley Grapewin and " 63 | /// "Clara Blandick, and the Singer Midgets as the Munchkins.\n" 64 | /// "\n" 65 | /// "Notable for its use of Technicolor, fantasy storytelling, musical score and " 66 | /// "unusual characters, over the years it has become an icon of American popular " 67 | /// "culture. It was nominated for six Academy Awards, including Best Picture but " 68 | /// "lost to Gone with the Wind. It did win in two other categories including Best " 69 | /// "Original Song for \"Over the Rainbow\". However, the film was a box office " 70 | /// "disappointment on its initial release, earning only $3,017,000 on a $2,777,000 " 71 | /// "budget, despite receiving largely positive reviews. It was MGM's most " 72 | /// "expensive production at that time, and did not completely recoup the studio's " 73 | /// "investment and turn a profit until theatrical re-releases starting in 1949.\n" 74 | /// "\n" 75 | /// "The 1956 broadcast television premiere of the film on CBS re-introduced the " 76 | /// "film to the wider public and eventually made the presentation an annual " 77 | /// "tradition, making it one of the most known films in cinema history. The " 78 | /// "film was named the most-viewed motion picture on television syndication by " 79 | /// "the Library of Congress who also included the film in its National Film " 80 | /// "Registry in its inaugural year in 1989. Designation on the registry calls " 81 | /// "for efforts to preserve it for being \"culturally, historically, and " 82 | /// "aesthetically significant\". It is also one of the few films on UNESCO's " 83 | /// "Memory of the World Register.\n" 84 | /// "\n" 85 | /// "The Wizard of Oz is often ranked on best-movie lists in critics' and public " 86 | /// "polls. It is the source of many quotes referenced in modern popular culture. " 87 | /// "It was directed primarily by Victor Fleming (who left production to take " 88 | /// "over direction on the troubled Gone with the Wind production). Noel Langley, " 89 | /// "Florence Ryerson and Edgar Allan Woolf received credit for the screenplay, " 90 | /// "but there were uncredited contributions by others. The songs were written " 91 | /// "by Edgar \"Yip\" Harburg (lyrics) and Harold Arlen (music). The incidental " 92 | /// "music, based largely on the songs, was composed by Herbert Stothart, with " 93 | /// "interspersed renderings from classical composers.\n"); 94 | /// ~~~~~~~~~~~~~ 95 | /// 96 | inline void Show(const std::string& heading, const std::string& text) 97 | { 98 | using namespace ::kodi::addon; 99 | CAddonBase::m_interface->toKodi->kodi_gui->dialogTextViewer->open(CAddonBase::m_interface->toKodi->kodiBase, heading.c_str(), text.c_str()); 100 | } 101 | //-------------------------------------------------------------------------- 102 | }; 103 | /// @} 104 | 105 | } /* namespace dialogs */ 106 | } /* namespace gui */ 107 | } /* namespace kodi */ 108 | -------------------------------------------------------------------------------- /include/kodi/libKODI_game.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libXBMC_addon.h" 12 | #include "kodi_game_types.h" 13 | 14 | #include 15 | #include 16 | 17 | #if defined(ANDROID) 18 | #include 19 | #endif 20 | 21 | class CHelper_libKODI_game 22 | { 23 | public: 24 | CHelper_libKODI_game(void) : 25 | m_handle(nullptr), 26 | m_callbacks(nullptr) 27 | { 28 | } 29 | 30 | ~CHelper_libKODI_game(void) 31 | { 32 | } 33 | 34 | /*! 35 | * @brief Resolve all callback methods 36 | * @param handle Pointer to the add-on 37 | * @return True when all methods were resolved, false otherwise. 38 | */ 39 | bool RegisterMe(void* handle) 40 | { 41 | m_handle = static_cast(handle); 42 | if (m_handle) 43 | m_callbacks = (AddonInstance_Game*)m_handle->GameLib_RegisterMe(m_handle->addonData); 44 | if (!m_callbacks) 45 | fprintf(stderr, "libKODI_game-ERROR: GameLib_RegisterMe can't get callback table from Kodi !!!\n"); 46 | 47 | return m_callbacks != nullptr; 48 | } 49 | 50 | // --- Game callbacks -------------------------------------------------------- 51 | 52 | /*! 53 | * \brief Requests the frontend to stop the current game 54 | */ 55 | void CloseGame(void) 56 | { 57 | m_callbacks->toKodi.CloseGame(m_callbacks->toKodi.kodiInstance); 58 | } 59 | 60 | /*! 61 | * \brief Create a stream for gameplay data 62 | * 63 | * \param properties The stream properties 64 | * 65 | * \return A stream handle, or NULL on failure 66 | */ 67 | void* OpenStream(const game_stream_properties &properties) 68 | { 69 | return m_callbacks->toKodi.OpenStream(m_callbacks->toKodi.kodiInstance, &properties); 70 | } 71 | 72 | /*! 73 | * \brief Get a buffer for zero-copy stream data 74 | * 75 | * \param stream The stream handle 76 | * \param width The framebuffer width, or 0 for no width specified 77 | * \param height The framebuffer height, or 0 for no height specified 78 | * \param[out] buffer The buffer, or unmodified if false is returned 79 | * 80 | * If this returns true, buffer must be freed using ReleaseStreamBuffer(). 81 | * 82 | * \return True if buffer was set, false otherwise 83 | */ 84 | bool GetStreamBuffer(void *stream, unsigned int width, unsigned int height, game_stream_buffer &buffer) 85 | { 86 | return m_callbacks->toKodi.GetStreamBuffer(m_callbacks->toKodi.kodiInstance, stream, width, height, &buffer); 87 | } 88 | 89 | /*! 90 | * \brief Add a data packet to a stream 91 | * 92 | * \param stream The target stream 93 | * \param packet The data packet 94 | */ 95 | void AddStreamData(void *stream, const game_stream_packet &packet) 96 | { 97 | m_callbacks->toKodi.AddStreamData(m_callbacks->toKodi.kodiInstance, stream, &packet); 98 | } 99 | 100 | /*! 101 | * \brief Free an allocated buffer 102 | * 103 | * \param stream The stream handle 104 | * \param buffer The buffer returned from GetStreamBuffer() 105 | */ 106 | void ReleaseStreamBuffer(void *stream, game_stream_buffer &buffer) 107 | { 108 | m_callbacks->toKodi.ReleaseStreamBuffer(m_callbacks->toKodi.kodiInstance, stream, &buffer); 109 | } 110 | 111 | /*! 112 | * \brief Free the specified stream 113 | * 114 | * \param stream The stream to close 115 | */ 116 | void CloseStream(void *stream) 117 | { 118 | m_callbacks->toKodi.CloseStream(m_callbacks->toKodi.kodiInstance, stream); 119 | } 120 | 121 | // -- Hardware rendering callbacks ------------------------------------------- 122 | 123 | /*! 124 | * \brief Get a symbol from the hardware context 125 | * 126 | * \param sym The symbol's name 127 | * 128 | * \return A function pointer for the specified symbol 129 | */ 130 | game_proc_address_t HwGetProcAddress(const char* sym) 131 | { 132 | return m_callbacks->toKodi.HwGetProcAddress(m_callbacks->toKodi.kodiInstance, sym); 133 | } 134 | 135 | // --- Input callbacks ------------------------------------------------------- 136 | 137 | /*! 138 | * \brief Notify the port of an input event 139 | * 140 | * \param event The input event 141 | * 142 | * Input events can arrive for the following sources: 143 | * - GAME_INPUT_EVENT_MOTOR 144 | * 145 | * \return true if the event was handled, false otherwise 146 | */ 147 | bool InputEvent(const game_input_event& event) 148 | { 149 | return m_callbacks->toKodi.InputEvent(m_callbacks->toKodi.kodiInstance, &event); 150 | } 151 | 152 | private: 153 | AddonCB* m_handle; 154 | AddonInstance_Game* m_callbacks; 155 | }; 156 | -------------------------------------------------------------------------------- /include/kodi/platform/android/System.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "../../AddonBase.h" 12 | 13 | /* 14 | * For interface between add-on and kodi. 15 | * 16 | * This structure defines the addresses of functions stored inside Kodi which 17 | * are then available for the add-on to call 18 | * 19 | * All function pointers there are used by the C++ interface functions below. 20 | * You find the set of them on xbmc/addons/interfaces/General.cpp 21 | * 22 | * Note: For add-on development itself this is not needed 23 | */ 24 | 25 | static const char* INTERFACE_ANDROID_SYSTEM_NAME = "ANDROID_SYSTEM"; 26 | static const char* INTERFACE_ANDROID_SYSTEM_VERSION = "1.0.1"; 27 | static const char* INTERFACE_ANDROID_SYSTEM_VERSION_MIN = "1.0.1"; 28 | 29 | struct AddonToKodiFuncTable_android_system 30 | { 31 | void* (*get_jni_env)(); 32 | int (*get_sdk_version)(); 33 | const char *(*get_class_name)(); 34 | }; 35 | 36 | //============================================================================== 37 | /// 38 | /// \defgroup cpp_kodi_platform Interface - kodi::platform 39 | /// \ingroup cpp 40 | /// @brief **Android platform specific functions** 41 | /// 42 | /// #include " 43 | /// 44 | //------------------------------------------------------------------------------ 45 | 46 | namespace kodi 47 | { 48 | namespace platform 49 | { 50 | class CInterfaceAndroidSystem 51 | { 52 | public: 53 | CInterfaceAndroidSystem() 54 | : m_interface(static_cast(GetInterface(INTERFACE_ANDROID_SYSTEM_NAME, INTERFACE_ANDROID_SYSTEM_VERSION))) 55 | {}; 56 | 57 | //============================================================================ 58 | /// 59 | /// \ingroup cpp_kodi_platform 60 | /// @brief request an JNI env pointer for the calling thread. 61 | /// JNI env has to be controlled by kodi because of the underlying 62 | /// threading concep. 63 | /// 64 | /// @param[in]: 65 | /// @return JNI env pointer for the calling thread 66 | /// 67 | inline void * GetJNIEnv() 68 | { 69 | if (m_interface) 70 | return m_interface->get_jni_env(); 71 | 72 | return nullptr; 73 | } 74 | //---------------------------------------------------------------------------- 75 | 76 | //============================================================================ 77 | /// 78 | /// \ingroup cpp_kodi_platform 79 | /// @brief request the android sdk version to e.g. initialize JNIBase. 80 | /// 81 | /// @param[in]: 82 | /// @return Android SDK version 83 | /// 84 | inline int GetSDKVersion() 85 | { 86 | if (m_interface) 87 | return m_interface->get_sdk_version(); 88 | 89 | return 0; 90 | } 91 | 92 | //============================================================================ 93 | /// 94 | /// \ingroup cpp_kodi_platform 95 | /// @brief request the android main class name e.g. org.xbmc.kodi. 96 | /// 97 | /// @param[in]: 98 | /// @return package class name 99 | /// 100 | inline std::string GetClassName() 101 | { 102 | if (m_interface) 103 | return m_interface->get_class_name(); 104 | 105 | return std::string(); 106 | } 107 | 108 | private: 109 | AddonToKodiFuncTable_android_system *m_interface; 110 | }; 111 | //---------------------------------------------------------------------------- 112 | } /* namespace platform */ 113 | } /* namespace kodi */ 114 | -------------------------------------------------------------------------------- /include/kodi/tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(HEADERS DllHelper.h ) 2 | 3 | if(NOT ENABLE_STATIC_LIBS) 4 | core_add_library(addons_kodi-addon-dev-kit_include_kodi_tools) 5 | endif() 6 | -------------------------------------------------------------------------------- /include/kodi/tools/DllHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #ifdef _WIN32 // windows 15 | #include 16 | #else 17 | #include // linux+osx 18 | #endif 19 | 20 | #define REGISTER_DLL_SYMBOL(functionPtr) \ 21 | CDllHelper::RegisterSymbol(functionPtr, #functionPtr) 22 | 23 | /// @brief Class to help with load of shared library functions 24 | /// 25 | /// You can add them as parent to your class and to help with load of shared 26 | /// library functions. 27 | /// 28 | /// @note To use on Windows must you also include p8-platform on your addon! 29 | /// 30 | /// 31 | /// ---------------------------------------------------------------------------- 32 | /// 33 | /// **Example:** 34 | /// ~~~~~~~~~~~~~{.cpp} 35 | /// 36 | /// #include 37 | /// 38 | /// ... 39 | /// class CMyInstance : public kodi::addon::CInstanceAudioDecoder, 40 | /// private CDllHelper 41 | /// { 42 | /// public: 43 | /// CMyInstance(KODI_HANDLE instance); 44 | /// bool Start(); 45 | /// 46 | /// ... 47 | /// 48 | /// /* The pointers for on shared library exported functions */ 49 | /// int (*Init)(); 50 | /// void (*Cleanup)(); 51 | /// int (*GetLength)(); 52 | /// }; 53 | /// 54 | /// CMyInstance::CMyInstance(KODI_HANDLE instance) 55 | /// : CInstanceAudioDecoder(instance) 56 | /// { 57 | /// } 58 | /// 59 | /// bool CMyInstance::Start() 60 | /// { 61 | /// std::string lib = kodi::GetAddonPath("myLib.so"); 62 | /// if (!LoadDll(lib)) return false; 63 | /// if (!REGISTER_DLL_SYMBOL(Init)) return false; 64 | /// if (!REGISTER_DLL_SYMBOL(Cleanup)) return false; 65 | /// if (!REGISTER_DLL_SYMBOL(GetLength)) return false; 66 | /// 67 | /// Init(); 68 | /// return true; 69 | /// } 70 | /// ... 71 | /// ~~~~~~~~~~~~~ 72 | /// 73 | class CDllHelper 74 | { 75 | public: 76 | CDllHelper() : m_dll(nullptr) { } 77 | virtual ~CDllHelper() 78 | { 79 | if (m_dll) 80 | dlclose(m_dll); 81 | } 82 | 83 | /// @brief Function to load requested library 84 | /// 85 | /// @param[in] path The path with filename of shared library to load 86 | /// @return true if load was successful done 87 | /// 88 | bool LoadDll(const std::string& path) 89 | { 90 | m_dll = dlopen(path.c_str(), RTLD_LAZY); 91 | if (m_dll == nullptr) 92 | { 93 | kodi::Log(ADDON_LOG_ERROR, "Unable to load %s", dlerror()); 94 | return false; 95 | } 96 | return true; 97 | } 98 | 99 | /// @brief Function to register requested library symbol 100 | /// 101 | /// @note This function should not be used, use instead the macro 102 | /// REGISTER_DLL_SYMBOL to register the symbol pointer. 103 | /// 104 | template 105 | bool RegisterSymbol(T& functionPtr, const char* strFunctionPtr) 106 | { 107 | functionPtr = reinterpret_cast(dlsym(m_dll, strFunctionPtr)); 108 | if (functionPtr == nullptr) 109 | { 110 | kodi::Log(ADDON_LOG_ERROR, "Unable to assign function %s", dlerror()); 111 | return false; 112 | } 113 | return true; 114 | } 115 | 116 | private: 117 | void* m_dll; 118 | }; 119 | -------------------------------------------------------------------------------- /include/kodi/xbmc_addon_dll.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "AddonBase.h" 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | ADDON_STATUS __declspec(dllexport) ADDON_Create(void *callbacks, void* props); 18 | ADDON_STATUS __declspec(dllexport) ADDON_CreateEx(void *callbacks, const char* globalApiVersion, void* props); 19 | void __declspec(dllexport) ADDON_Destroy(); 20 | ADDON_STATUS __declspec(dllexport) ADDON_GetStatus(); 21 | ADDON_STATUS __declspec(dllexport) ADDON_SetSetting(const char *settingName, const void *settingValue); 22 | __declspec(dllexport) const char* ADDON_GetTypeVersion(int type) 23 | { 24 | return kodi::addon::GetTypeVersion(type); 25 | } 26 | __declspec(dllexport) const char* ADDON_GetTypeMinVersion(int type) 27 | { 28 | return kodi::addon::GetTypeMinVersion(type); 29 | } 30 | 31 | #ifdef __cplusplus 32 | }; 33 | #endif 34 | -------------------------------------------------------------------------------- /include/kodi/xbmc_addon_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "AddonBase.h" // compatibility fallback 12 | -------------------------------------------------------------------------------- /include/kodi/xbmc_epg_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2018 Team Kodi 3 | * This file is part of Kodi - https://kodi.tv 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * See LICENSES/README.md for more information. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #undef ATTRIBUTE_PACKED 15 | #undef PRAGMA_PACK_BEGIN 16 | #undef PRAGMA_PACK_END 17 | 18 | #if defined(__GNUC__) 19 | #define ATTRIBUTE_PACKED __attribute__ ((packed)) 20 | #define PRAGMA_PACK 0 21 | #endif 22 | 23 | #if !defined(ATTRIBUTE_PACKED) 24 | #define ATTRIBUTE_PACKED 25 | #define PRAGMA_PACK 1 26 | #endif 27 | 28 | /*! @name EPG entry content event types */ 29 | //@{ 30 | /* These IDs come from the DVB-SI EIT table "content descriptor" 31 | * Also known under the name "E-book genre assignments" 32 | */ 33 | #define EPG_EVENT_CONTENTMASK_UNDEFINED 0x00 34 | #define EPG_EVENT_CONTENTMASK_MOVIEDRAMA 0x10 35 | #define EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS 0x20 36 | #define EPG_EVENT_CONTENTMASK_SHOW 0x30 37 | #define EPG_EVENT_CONTENTMASK_SPORTS 0x40 38 | #define EPG_EVENT_CONTENTMASK_CHILDRENYOUTH 0x50 39 | #define EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE 0x60 40 | #define EPG_EVENT_CONTENTMASK_ARTSCULTURE 0x70 41 | #define EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS 0x80 42 | #define EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE 0x90 43 | #define EPG_EVENT_CONTENTMASK_LEISUREHOBBIES 0xA0 44 | #define EPG_EVENT_CONTENTMASK_SPECIAL 0xB0 45 | #define EPG_EVENT_CONTENTMASK_USERDEFINED 0xF0 46 | //@} 47 | 48 | /* Set EPGTAG.iGenreType to EPG_GENRE_USE_STRING to transfer genre strings to Kodi */ 49 | #define EPG_GENRE_USE_STRING 0x100 50 | 51 | /* Separator to use in strings containing different tokens, for example writers, directors, actors of an event. */ 52 | #define EPG_STRING_TOKEN_SEPARATOR "," 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | /* EPG_TAG.iFlags values */ 59 | const unsigned int EPG_TAG_FLAG_UNDEFINED = 0x00000000; /*!< @brief nothing special to say about this entry */ 60 | const unsigned int EPG_TAG_FLAG_IS_SERIES = 0x00000001; /*!< @brief this EPG entry is part of a series */ 61 | 62 | /* Special EPG_TAG.iUniqueBroadcastId value */ 63 | 64 | /*! 65 | * @brief special EPG_TAG.iUniqueBroadcastId value to indicate that a tag has not a valid EPG event uid. 66 | */ 67 | const unsigned int EPG_TAG_INVALID_UID = 0; 68 | 69 | /*! 70 | * @brief EPG event states. Used with EpgEventStateChange callback. 71 | */ 72 | typedef enum 73 | { 74 | EPG_EVENT_CREATED = 0, /*!< @brief event created */ 75 | EPG_EVENT_UPDATED = 1, /*!< @brief event updated */ 76 | EPG_EVENT_DELETED = 2, /*!< @brief event deleted */ 77 | } EPG_EVENT_STATE; 78 | 79 | /*! 80 | * @brief Representation of an EPG event. 81 | */ 82 | typedef struct EPG_TAG { 83 | unsigned int iUniqueBroadcastId; /*!< @brief (required) identifier for this event. Event uids must be unique for a channel. Valid uids must be greater than EPG_TAG_INVALID_UID. */ 84 | unsigned int iUniqueChannelId; /*!< @brief (required) unique identifier of the channel this event belongs to. */ 85 | const char * strTitle; /*!< @brief (required) this event's title */ 86 | time_t startTime; /*!< @brief (required) start time in UTC */ 87 | time_t endTime; /*!< @brief (required) end time in UTC */ 88 | const char * strPlotOutline; /*!< @brief (optional) plot outline */ 89 | const char * strPlot; /*!< @brief (optional) plot */ 90 | const char * strOriginalTitle; /*!< @brief (optional) originaltitle */ 91 | const char * strCast; /*!< @brief (optional) cast. Use EPG_STRING_TOKEN_SEPARATOR to separate different persons. */ 92 | const char * strDirector; /*!< @brief (optional) director(s). Use EPG_STRING_TOKEN_SEPARATOR to separate different persons. */ 93 | const char * strWriter; /*!< @brief (optional) writer(s). Use EPG_STRING_TOKEN_SEPARATOR to separate different persons. */ 94 | int iYear; /*!< @brief (optional) year */ 95 | const char * strIMDBNumber; /*!< @brief (optional) IMDBNumber */ 96 | const char * strIconPath; /*!< @brief (optional) icon path */ 97 | int iGenreType; /*!< @brief (optional) genre type */ 98 | int iGenreSubType; /*!< @brief (optional) genre sub type */ 99 | const char * strGenreDescription; /*!< @brief (optional) genre. Will be used only when iGenreType == EPG_GENRE_USE_STRING. Use EPG_STRING_TOKEN_SEPARATOR to separate different genres. */ 100 | time_t firstAired; /*!< @brief (optional) first aired in UTC */ 101 | int iParentalRating; /*!< @brief (optional) parental rating */ 102 | int iStarRating; /*!< @brief (optional) star rating */ 103 | bool bNotify; /*!< @brief (optional) notify the user when this event starts */ 104 | int iSeriesNumber; /*!< @brief (optional) series number */ 105 | int iEpisodeNumber; /*!< @brief (optional) episode number */ 106 | int iEpisodePartNumber; /*!< @brief (optional) episode part number */ 107 | const char * strEpisodeName; /*!< @brief (optional) episode name */ 108 | unsigned int iFlags; /*!< @brief (optional) bit field of independent flags associated with the EPG entry */ 109 | const char * strSeriesLink; /*!< @brief (optional) series link for this event */ 110 | } ATTRIBUTE_PACKED EPG_TAG; 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif 115 | -------------------------------------------------------------------------------- /include/picojson/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2009-2010 Cybozu Labs, Inc. 2 | Copyright 2011-2014 Kazuho Oku 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir)/.. 2 | 3 | ## chinachu 4 | include $(CLEAR_VARS) 5 | 6 | LOCAL_MODULE := chinachu 7 | 8 | LOCAL_SRC_FILES := $(wildcard src/chinachu/*.cpp) 9 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 10 | 11 | include $(BUILD_STATIC_LIBRARY) 12 | 13 | ## pvr_client 14 | include $(CLEAR_VARS) 15 | 16 | LOCAL_MODULE := pvr.chinachu 17 | 18 | LOCAL_SRC_FILES := $(wildcard src/pvr_client/*.cpp) 19 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/src 20 | LOCAL_STATIC_LIBRARIES := chinachu 21 | 22 | include $(BUILD_SHARED_LIBRARY) 23 | -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_PROJECT_PATH := $(NDK_PROJECT_PATH) 2 | APP_CPPFLAGS := -Werror -std=c++11 -frtti -fexceptions -Wall -DANDROID -DPICOJSON_USE_LOCALE=0 -DPICOJSON_USE_RVALUE_REFERENCE=0 3 | APP_STL := c++_static 4 | APP_PLATFORM := android-16 5 | APP_OPTIM := release 6 | APP_ABI := armeabi-v7a 7 | -------------------------------------------------------------------------------- /jni/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ADDONNAME=libpvr.chinachu.so 4 | 5 | if [ $# -eq 0 ]; then 6 | echo "usage: $0 APP_ABI=armeabi-v7a" 7 | exit 1 8 | fi 9 | export "$1" 10 | if [ -z ${APP_ABI+x} ]; then 11 | echo "APP_ABI is unset" 12 | exit 1 13 | fi 14 | if [ ! -e libs/${APP_ABI}/${ADDONNAME} ]; then 15 | echo "build first." 16 | exit 1 17 | fi 18 | 19 | set -eux 20 | which zip 21 | mkdir -p dist 22 | cp -r template/pvr.chinachu dist/ 23 | cp ChangeLog.txt dist/pvr.chinachu/ 24 | cp LICENSE dist/pvr.chinachu/ 25 | cp libs/${APP_ABI}/${ADDONNAME} dist/pvr.chinachu/${ADDONNAME} 26 | cd dist; zip -9 -r ../pvr.chinachu.zip pvr.chinachu 27 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = chinachu pvr_client 2 | 3 | clean-local: 4 | rm -f $(ADDONNAME) 5 | -------------------------------------------------------------------------------- /src/chinachu/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_LTLIBRARIES = libchinachu.la 2 | 3 | libchinachu_la_SOURCES = \ 4 | api.cpp \ 5 | api.h \ 6 | chinachu.h \ 7 | recorded.cpp \ 8 | recorded.h \ 9 | recording.cpp \ 10 | recording.h \ 11 | reserves.cpp \ 12 | reserves.h \ 13 | rules.cpp \ 14 | rules.h \ 15 | schedule.cpp \ 16 | schedule.h 17 | 18 | libchinachu_la_LDFLAGS = \ 19 | -avoid-version 20 | 21 | AM_CPPFLAGS = \ 22 | $(AM_CPPFLAGS_EXT) \ 23 | -std=c++11 \ 24 | -I. \ 25 | -I$(top_srcdir)/include -I$(top_srcdir)/src 26 | 27 | EXTRA_DIST = \ 28 | include 29 | 30 | all: libchinachu.la 31 | -------------------------------------------------------------------------------- /src/chinachu/api.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include "api.h" 23 | #include "kodi/libXBMC_pvr.h" 24 | #include "kodi/libXBMC_addon.h" 25 | 26 | extern ADDON::CHelper_libXBMC_addon *XBMC; 27 | extern CHelper_libXBMC_pvr *PVR; 28 | 29 | namespace chinachu { 30 | namespace api { 31 | const int REQUEST_FAILED = -1; 32 | std::string baseURL = ""; 33 | 34 | int requestGET(std::string apiPath, picojson::value &response) { 35 | std::string text; 36 | const std::string url = baseURL + apiPath; 37 | if (void* handle = XBMC->OpenFile(url.c_str(), 0)) { 38 | const unsigned int buffer_size = 4096; 39 | char buffer[buffer_size]; 40 | text.clear(); 41 | while (int bytesRead = XBMC->ReadFile(handle, buffer, buffer_size)) { 42 | text.append(buffer, bytesRead); 43 | } 44 | XBMC->CloseFile(handle); 45 | } else { 46 | XBMC->Log(ADDON::LOG_ERROR, "[%s] Request failed", apiPath.c_str()); 47 | XBMC->QueueNotification(ADDON::QUEUE_ERROR, "[%s] Request failed", apiPath.c_str()); 48 | return REQUEST_FAILED; 49 | } 50 | 51 | const std::string err = picojson::parse(response, text); 52 | if (!err.empty()) { 53 | XBMC->Log(ADDON::LOG_ERROR, "[%s] Failed to parse JSON string: %s", apiPath.c_str(), err.c_str()); 54 | XBMC->QueueNotification(ADDON::QUEUE_ERROR, "[%s] Failed to parse JSON string: %s", apiPath.c_str(), err.c_str()); 55 | return REQUEST_FAILED; 56 | } 57 | 58 | return text.length(); 59 | } 60 | 61 | int requestDELETE(std::string apiPath) { 62 | const std::string url = baseURL + apiPath; 63 | if (void* handle = XBMC->OpenFileForWrite(url.c_str(), 0)) { 64 | const unsigned int buffer_size = 20; 65 | const char buffer[] = "{\"_method\":\"DELETE\"}"; 66 | XBMC->WriteFile(handle, buffer, buffer_size); 67 | XBMC->CloseFile(handle); 68 | return 0; 69 | } else { 70 | return REQUEST_FAILED; 71 | } 72 | } 73 | 74 | int requestPUT(std::string apiPath) { 75 | const std::string url = baseURL + apiPath; 76 | if (void* handle = XBMC->OpenFileForWrite(url.c_str(), 0)) { 77 | const unsigned int buffer_size = 17; 78 | const char buffer[] = "{\"_method\":\"PUT\"}"; 79 | XBMC->WriteFile(handle, buffer, buffer_size); 80 | XBMC->CloseFile(handle); 81 | return 0; 82 | } else { 83 | return REQUEST_FAILED; 84 | } 85 | } 86 | 87 | int requestPOST(std::string apiPath, const char buffer[], const unsigned int buffer_size) { 88 | const std::string url = baseURL + apiPath; 89 | if (void* handle = XBMC->OpenFileForWrite(url.c_str(), 0)) { 90 | XBMC->WriteFile(handle, buffer, buffer_size); 91 | XBMC->CloseFile(handle); 92 | return 0; 93 | } else { 94 | return REQUEST_FAILED; 95 | } 96 | } 97 | 98 | // GET /schedule.json 99 | int getSchedule(picojson::value &response) { 100 | const std::string apiPath = "schedule.json"; 101 | return requestGET(apiPath, response); 102 | } 103 | 104 | // GET /recorded.json 105 | int getRecorded(picojson::value &response) { 106 | const std::string apiPath = "recorded.json"; 107 | return requestGET(apiPath, response); 108 | } 109 | 110 | // GET /recording.json 111 | int getRecording(picojson::value &response) { 112 | const std::string apiPath = "recording.json"; 113 | return requestGET(apiPath, response); 114 | } 115 | 116 | // GET /reserves.json 117 | int getReserves(picojson::value &response) { 118 | const std::string apiPath = "reserves.json"; 119 | return requestGET(apiPath, response); 120 | } 121 | 122 | // DELETE /recorded/:id.json 123 | int deleteRecordedProgram(std::string id) { 124 | const std::string apiPath = "recorded/" + id + ".json"; 125 | return requestDELETE(apiPath); 126 | } 127 | 128 | // DELETE /recording/:id.json 129 | int deleteRecordingProgram(std::string id) { 130 | const std::string apiPath = "recording/" + id + ".json"; 131 | return requestDELETE(apiPath); 132 | } 133 | 134 | // PUT /reserves/:id/skip.json 135 | int putReservesSkip(std::string id) { 136 | const std::string apiPath = "reserves/" + id + "/skip.json"; 137 | return requestPUT(apiPath); 138 | } 139 | 140 | // PUT /reserves/:id/unskip.json 141 | int putReservesUnskip(std::string id) { 142 | const std::string apiPath = "reserves/" + id + "/unskip.json"; 143 | return requestPUT(apiPath); 144 | } 145 | 146 | // PUT /program/:id.json 147 | int putProgram(std::string id) { 148 | const std::string apiPath = "program/" + id + ".json"; 149 | return requestPUT(apiPath); 150 | } 151 | 152 | // GET /rules.json 153 | int getRules(picojson::value &response) { 154 | const std::string apiPath = "rules.json"; 155 | return requestGET(apiPath, response); 156 | } 157 | 158 | // POST /rules.json 159 | int postRule(std::string type, std::string channel, std::string title, std::string genre) { 160 | const std::string apiPath = "rules.json"; 161 | std::string buffer = "{\"types\":[\"\"],\"channels\":[\"\"],\"hour\":{\"start\":0,\"end\":24},\"reserve_titles\":[\"\"],\"categories\":[\"\"],\"_method\":\"POST\"}"; 162 | buffer.replace(95, 0, genre); 163 | buffer.replace(77, 0, title); 164 | buffer.replace(27, 0, channel); 165 | buffer.replace(11, 0, type); 166 | return requestPOST(apiPath, buffer.c_str(), buffer.size()); 167 | } 168 | 169 | // PUT /rules/:id/:action.json 170 | int putRuleAction(int id, bool state) { 171 | const std::string apiPath = "rules/" + std::to_string(id) + (state ? "/enable" : "/disable") + ".json"; 172 | return requestPUT(apiPath); 173 | } 174 | 175 | // DELETE /reserves/:id.json 176 | int deleteReserves(std::string id) { 177 | const std::string apiPath = "reserves/" + id + ".json"; 178 | return requestDELETE(apiPath); 179 | } 180 | 181 | // PUT /scheduler.json 182 | int putScheduler() { 183 | const std::string apiPath = "scheduler.json"; 184 | return requestPUT(apiPath); 185 | } 186 | 187 | // GET /storage.json 188 | int getStorage(picojson::value &response) { 189 | const std::string apiPath = "storage.json"; 190 | return requestGET(apiPath, response); 191 | } 192 | 193 | } // namespace api 194 | } // namespace chinachu 195 | -------------------------------------------------------------------------------- /src/chinachu/api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_API_H 23 | #define CHINACHU_API_H 24 | 25 | #include 26 | #include "picojson/picojson.h" 27 | 28 | namespace chinachu { 29 | namespace api { 30 | extern const int REQUEST_FAILED; 31 | extern std::string baseURL; 32 | 33 | // GET /schedule.json 34 | int getSchedule(picojson::value &response); 35 | 36 | // GET /recorded.json 37 | int getRecorded(picojson::value &response); 38 | 39 | // GET /recording.json 40 | int getRecording(picojson::value &response); 41 | 42 | // GET /reserves.json 43 | int getReserves(picojson::value &response); 44 | 45 | // DELETE /recorded/:id.json 46 | int deleteRecordedProgram(std::string id); 47 | 48 | // DELETE /recording/:id.json 49 | int deleteRecordingProgram(std::string id); 50 | 51 | // PUT /reserves/:id/skip.json 52 | int putReservesSkip(std::string id); 53 | 54 | // PUT /reserves/:id/unskip.json 55 | int putReservesUnskip(std::string id); 56 | 57 | // PUT /program/:id.json 58 | int putProgram(std::string id); 59 | 60 | // GET /rules.json 61 | int getRules(picojson::value &response); 62 | 63 | // POST /rules.json 64 | int postRule(std::string type, std::string channel, std::string title, std::string genre); 65 | 66 | // PUT /rules/:id/:action.json 67 | int putRuleAction(int id, bool state); 68 | 69 | // DELETE /reserves/:id.json 70 | int deleteReserves(std::string id); 71 | 72 | // PUT /scheduler.json 73 | int putScheduler(); 74 | 75 | // GET /storage.json 76 | int getStorage(picojson::value &response); 77 | 78 | } // namespace api 79 | } // namespace chinachu 80 | 81 | #endif /* end of include guard */ 82 | -------------------------------------------------------------------------------- /src/chinachu/chinachu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_CHINACHU_H 23 | #define CHINACHU_CHINACHU_H 24 | 25 | #include "schedule.h" 26 | #include "recorded.h" 27 | #include "recording.h" 28 | #include "reserves.h" 29 | #include "rules.h" 30 | #include "api.h" 31 | 32 | #endif /* end of include guard */ 33 | -------------------------------------------------------------------------------- /src/chinachu/recorded.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include "api.h" 23 | #include "recorded.h" 24 | #include "schedule.h" 25 | #include "kodi/libXBMC_addon.h" 26 | 27 | extern ADDON::CHelper_libXBMC_addon *XBMC; 28 | 29 | 30 | namespace chinachu { 31 | bool Recorded::refresh() { 32 | picojson::value response; 33 | 34 | if (chinachu::api::getRecorded(response) == chinachu::api::REQUEST_FAILED) { 35 | return false; 36 | } 37 | 38 | const bool showThumbnail = !recordedThumbnailPath.empty(); 39 | programs.clear(); 40 | 41 | for (picojson::value &a: response.get()) { 42 | picojson::object &p = a.get(); 43 | PVR_RECORDING rec; 44 | char *endptr; 45 | 46 | strncpy(rec.strRecordingId, p["id"].is() ? p["id"].get().c_str() : "", PVR_ADDON_NAME_STRING_LENGTH - 1); 47 | strncpy(rec.strDirectory, p["title"].is() ? p["title"].get().c_str() : "", PVR_ADDON_URL_STRING_LENGTH - 1); 48 | strncpy(rec.strTitle, p["title"].is() ? p["title"].get().c_str() : "", PVR_ADDON_NAME_STRING_LENGTH - 1); 49 | strncpy(rec.strEpisodeName, p["subTitle"].is() ? p["subTitle"].get().c_str() : "", PVR_ADDON_NAME_STRING_LENGTH - 1); 50 | strncpy(rec.strPlotOutline, p["description"].is() ? p["description"].get().c_str() : rec.strEpisodeName, PVR_ADDON_DESC_STRING_LENGTH - 1); 51 | strncpy(rec.strPlot, p["detail"].is() ? p["detail"].get().c_str() : "", PVR_ADDON_DESC_STRING_LENGTH - 1); 52 | strncpy(rec.strChannelName, (p["channel"].get())["name"].get().c_str(), PVR_ADDON_NAME_STRING_LENGTH - 1); 53 | rec.iEpisodeNumber = p["episode"].is() ? (unsigned int)(p["episode"].get()) : 0; 54 | rec.recordingTime = (time_t)(p["start"].get() / 1000); 55 | rec.iDuration = (int)(p["seconds"].get()); 56 | rec.iPriority = p["priority"].is() ? (int)(p["priority"].get()) : 0; 57 | const std::string strGenreType = p["category"].get(); 58 | rec.iGenreType = chinachu::iGenreTypePair[strGenreType] & chinachu::GENRE_TYPE_MASK; 59 | rec.iGenreSubType = chinachu::iGenreTypePair[strGenreType] & chinachu::GENRE_SUBTYPE_MASK; 60 | std::string id = p["id"].get(); 61 | std::remove(id.begin(), id.end(), '-'); 62 | const std::string strSubstrId = id.substr(id.size() - 6, 6); 63 | rec.iEpgEventId = strtoul(strSubstrId.c_str(), &endptr, 36); 64 | rec.channelType = PVR_RECORDING_CHANNEL_TYPE_TV; 65 | rec.bIsDeleted = false; 66 | const int sid = p["channel"].get()["sid"].is() ? 67 | std::atoi((p["channel"].get()["sid"].get()).c_str()) : 68 | (int)(p["channel"].get()["sid"].get()); 69 | rec.iChannelUid = sid; 70 | if (showThumbnail) { 71 | snprintf(rec.strThumbnailPath, PVR_ADDON_URL_STRING_LENGTH - 1, (const char*)(chinachu::api::baseURL + recordedThumbnailPath).c_str(), p["id"].get().c_str()); 72 | } else { 73 | strncpy(rec.strThumbnailPath, "", PVR_ADDON_URL_STRING_LENGTH - 1); 74 | } 75 | 76 | programs.push_back(rec); 77 | } 78 | 79 | XBMC->Log(ADDON::LOG_NOTICE, "Updated recorded program: ammount = %d", programs.size()); 80 | 81 | return true; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/chinachu/recorded.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_RECORDED_H 23 | #define CHINACHU_RECORDED_H 24 | #include 25 | 26 | #include "picojson/picojson.h" 27 | #include "chinachu/genre.h" 28 | #include "kodi/xbmc_pvr_types.h" 29 | 30 | namespace chinachu { 31 | class Recorded { 32 | public: 33 | std::string recordedStreamingPath; 34 | std::string recordedThumbnailPath; 35 | std::vector programs; 36 | bool refresh(); 37 | }; 38 | } // namespace chinachu 39 | 40 | #endif /* end of include guard */ 41 | -------------------------------------------------------------------------------- /src/chinachu/recording.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include "api.h" 23 | #include "recorded.h" 24 | #include "recording.h" 25 | #include "schedule.h" 26 | #include "kodi/libXBMC_addon.h" 27 | 28 | extern ADDON::CHelper_libXBMC_addon *XBMC; 29 | 30 | 31 | namespace chinachu { 32 | bool Recording::refresh() { 33 | picojson::value response; 34 | 35 | if (chinachu::api::getRecording(response) == chinachu::api::REQUEST_FAILED) { 36 | return false; 37 | } 38 | 39 | const bool showThumbnail = !recordingThumbnailPath.empty(); 40 | programs.clear(); 41 | 42 | for (picojson::value &a: response.get()) { 43 | picojson::object &p = a.get(); 44 | PVR_RECORDING rec; 45 | char *endptr; 46 | 47 | strncpy(rec.strRecordingId, p["id"].is() ? p["id"].get().c_str() : "", PVR_ADDON_NAME_STRING_LENGTH - 1); 48 | strncpy(rec.strDirectory, p["title"].is() ? p["title"].get().c_str() : "", PVR_ADDON_URL_STRING_LENGTH - 1); 49 | strncpy(rec.strTitle, p["title"].is() ? p["title"].get().c_str() : "", PVR_ADDON_NAME_STRING_LENGTH - 1); 50 | strncpy(rec.strEpisodeName, p["subTitle"].is() ? p["subTitle"].get().c_str() : "", PVR_ADDON_NAME_STRING_LENGTH - 1); 51 | strncpy(rec.strPlotOutline, p["description"].is() ? p["description"].get().c_str() : rec.strEpisodeName, PVR_ADDON_DESC_STRING_LENGTH - 1); 52 | strncpy(rec.strPlot, p["detail"].is() ? p["detail"].get().c_str() : "", PVR_ADDON_DESC_STRING_LENGTH - 1); 53 | strncpy(rec.strChannelName, (p["channel"].get())["name"].get().c_str(), PVR_ADDON_NAME_STRING_LENGTH - 1); 54 | rec.iEpisodeNumber = p["episode"].is() ? (unsigned int)(p["episode"].get()) : 0; 55 | rec.recordingTime = (time_t)(p["start"].get() / 1000); 56 | rec.iDuration = (int)(p["seconds"].get()); 57 | rec.iPriority = p["priority"].is() ? (int)(p["priority"].get()) : 0; 58 | const std::string strGenreType = p["category"].get(); 59 | rec.iGenreType = chinachu::iGenreTypePair[strGenreType] & chinachu::GENRE_TYPE_MASK; 60 | rec.iGenreSubType = chinachu::iGenreTypePair[strGenreType] & chinachu::GENRE_SUBTYPE_MASK; 61 | std::string id = p["id"].get(); 62 | std::remove(id.begin(), id.end(), '-'); 63 | const std::string strSubstrId = id.substr(id.size() - 6, 6); 64 | rec.iEpgEventId = strtoul(strSubstrId.c_str(), &endptr, 36); 65 | rec.channelType = PVR_RECORDING_CHANNEL_TYPE_TV; 66 | rec.bIsDeleted = false; 67 | const int sid = p["channel"].get()["sid"].is() ? 68 | std::atoi((p["channel"].get()["sid"].get()).c_str()) : 69 | (int)(p["channel"].get()["sid"].get()); 70 | rec.iChannelUid = sid; 71 | if (showThumbnail) { 72 | snprintf(rec.strThumbnailPath, PVR_ADDON_URL_STRING_LENGTH - 1, (const char*)(chinachu::api::baseURL + recordingThumbnailPath).c_str(), p["id"].get().c_str()); 73 | } else { 74 | strncpy(rec.strThumbnailPath, "", PVR_ADDON_URL_STRING_LENGTH - 1); 75 | } 76 | 77 | programs.push_back(rec); 78 | } 79 | 80 | XBMC->Log(ADDON::LOG_NOTICE, "Updated recording program: ammount = %d", programs.size()); 81 | 82 | return true; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/chinachu/recording.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_RECORDING_H 23 | #define CHINACHU_RECORDING_H 24 | #include 25 | 26 | #include "picojson/picojson.h" 27 | #include "chinachu/genre.h" 28 | #include "kodi/xbmc_pvr_types.h" 29 | 30 | namespace chinachu { 31 | class Recording { 32 | public: 33 | std::string recordingStreamingPath; 34 | std::string recordingThumbnailPath; 35 | std::vector programs; 36 | bool refresh(); 37 | }; 38 | } // namespace chinachu 39 | 40 | #endif /* end of include guard */ 41 | -------------------------------------------------------------------------------- /src/chinachu/reserves.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include "api.h" 23 | #include "reserves.h" 24 | #include "recorded.h" 25 | #include "recording.h" 26 | #include "schedule.h" 27 | #include "kodi/libXBMC_addon.h" 28 | 29 | extern ADDON::CHelper_libXBMC_addon *XBMC; 30 | 31 | 32 | namespace chinachu { 33 | bool Reserve::refresh() { 34 | picojson::value response; 35 | 36 | if (chinachu::api::getReserves(response) == chinachu::api::REQUEST_FAILED) { 37 | return false; 38 | } 39 | 40 | reserves.clear(); 41 | 42 | time_t now; 43 | time(&now); 44 | 45 | for (picojson::value &a: response.get()) { 46 | picojson::object &p = a.get(); 47 | // Skip past tv program 48 | if ((p["end"].get() / 1000) < now) { 49 | continue; 50 | } 51 | struct PVR_TIMER resv; 52 | char *endptr; 53 | 54 | const std::string strSubstrId = p["id"].get().substr(p["id"].get().size() - 6, 6); 55 | resv.iEpgUid = strtoul(strSubstrId.c_str(), &endptr, 36); 56 | resv.iClientIndex = resv.iEpgUid; 57 | resv.iClientChannelUid = p["channel"].get()["sid"].is() ? 58 | std::atoi((p["channel"].get()["sid"].get()).c_str()) : 59 | (int)(p["channel"].get()["sid"].get()); 60 | strncpy(resv.strTitle, p["fullTitle"].get().c_str(), PVR_ADDON_NAME_STRING_LENGTH - 1); 61 | strncpy(resv.strSummary, p["detail"].get().c_str(), PVR_ADDON_DESC_STRING_LENGTH - 1); 62 | strncpy(resv.strDirectory, p["id"].get().c_str(), PVR_ADDON_URL_STRING_LENGTH - 1); // instead of strProgramId 63 | if (p["isConflict"].is() && p["isConflict"].get()) { 64 | resv.state = PVR_TIMER_STATE_CONFLICT_NOK; 65 | } else if (p["isSkip"].is() && p["isSkip"].get()) { 66 | resv.state = PVR_TIMER_STATE_DISABLED; 67 | } else { 68 | resv.state = PVR_TIMER_STATE_SCHEDULED; 69 | } 70 | resv.startTime = (time_t)(p["start"].get() / 1000); 71 | resv.endTime = (time_t)(p["end"].get() / 1000); 72 | resv.iGenreType = chinachu::iGenreTypePair[p["category"].get()] & chinachu::GENRE_TYPE_MASK; 73 | resv.iGenreSubType = chinachu::iGenreTypePair[p["category"].get()] & chinachu::GENRE_SUBTYPE_MASK; 74 | resv.bStartAnyTime = false; 75 | resv.bEndAnyTime = false; 76 | resv.iTimerType = (p["isManualReserved"].is() && p["isManualReserved"].get()) ? TIMER_MANUAL_RESERVED : TIMER_PATTERN_MATCHED; 77 | 78 | reserves.push_back(resv); 79 | } 80 | 81 | XBMC->Log(ADDON::LOG_NOTICE, "Updated reserved program: ammount = %d", reserves.size()); 82 | 83 | return true; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/chinachu/reserves.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_RESERVES_H 23 | #define CHINACHU_RESERVES_H 24 | #include 25 | 26 | #include "picojson/picojson.h" 27 | #include "chinachu/genre.h" 28 | #include "kodi/xbmc_pvr_types.h" 29 | 30 | #define TIMER_MANUAL_RESERVED 0x01 31 | #define TIMER_PATTERN_MATCHED 0x02 32 | 33 | namespace chinachu { 34 | class Reserve { 35 | public: 36 | std::vector reserves; 37 | bool refresh(); 38 | }; 39 | } // namespace chinachu 40 | 41 | #endif /* end of include guard */ 42 | -------------------------------------------------------------------------------- /src/chinachu/rules.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include "api.h" 23 | #include "reserves.h" 24 | #include "rules.h" 25 | #include "recorded.h" 26 | #include "recording.h" 27 | #include "schedule.h" 28 | #include "kodi/libXBMC_addon.h" 29 | 30 | extern ADDON::CHelper_libXBMC_addon *XBMC; 31 | 32 | 33 | namespace chinachu { 34 | bool Rule::refresh() { 35 | picojson::value response; 36 | 37 | if (chinachu::api::getRules(response) == chinachu::api::REQUEST_FAILED) { 38 | return false; 39 | } 40 | 41 | rules.clear(); 42 | 43 | unsigned int i = 0; 44 | for (picojson::value &a: response.get()) { 45 | picojson::object &p = a.get(); 46 | 47 | if (p["ignore_channels"].is() && !p["ignore_channels"].get().empty()) { 48 | XBMC->Log(ADDON::LOG_DEBUG, "Skipped - ignore channels specified rule: %d", i); 49 | continue; 50 | } 51 | 52 | if (p["reserve_titles"].is() && !p["reserve_titles"].get().empty() && 53 | p["reserve_descriptions"].is() && !p["reserve_descriptions"].get().empty()) { 54 | XBMC->Log(ADDON::LOG_DEBUG, "Skipped - multi reserve pattern rule: %d", i); 55 | continue; 56 | } 57 | if (p["ignore_titles"].is() && !p["ignore_titles"].get().empty() && 58 | p["ignore_descriptions"].is() && !p["ignore_descriptions"].get().empty()) { 59 | XBMC->Log(ADDON::LOG_DEBUG, "Skipped - multi ignore pattern rule: %d", i); 60 | continue; 61 | } 62 | if (p["reserve_titles"].is() && !p["reserve_titles"].get().empty() && 63 | p["ignore_descriptions"].is() && !p["ignore_descriptions"].get().empty()) { 64 | XBMC->Log(ADDON::LOG_DEBUG, "Skipped - multi reserve/ignore pattern rule: %d", i); 65 | continue; 66 | } 67 | 68 | struct RULE_ITEM rule; 69 | rule.iIndex = i++; 70 | 71 | if (p["reserve_titles"].is() && !p["reserve_titles"].get().empty()) { 72 | rule.bFullTextEpgSearch = false; 73 | rule.strEpgSearchString = ""; 74 | for (picojson::value &r: p["reserve_titles"].get()) { 75 | if (r != *p["reserve_titles"].get().begin()) 76 | rule.strEpgSearchString += ", "; 77 | rule.strEpgSearchString += r.get(); 78 | } 79 | if (p["ignore_titles"].is() && !p["ignore_titles"].get().empty()) { 80 | for (picojson::value &r: p["ignore_titles"].get()) { 81 | rule.strEpgSearchString += ", -"; 82 | rule.strEpgSearchString += r.get(); 83 | } 84 | } 85 | } else if (p["reserve_descriptions"].is() && !p["reserve_descriptions"].get().empty()) { 86 | rule.bFullTextEpgSearch = true; 87 | rule.strEpgSearchString = p["reserve_descriptions"].get()[0].get(); 88 | for (picojson::value &r: p["reserve_descriptions"].get()) { 89 | if (r != *p["reserve_descriptions"].get().begin()) 90 | rule.strEpgSearchString += ", "; 91 | rule.strEpgSearchString += r.get(); 92 | } 93 | if (p["ignore_descriptions"].is() && !p["ignore_descriptions"].get().empty()) { 94 | for (picojson::value &r: p["ignore_descriptions"].get()) { 95 | rule.strEpgSearchString += ", -"; 96 | rule.strEpgSearchString += r.get(); 97 | } 98 | } 99 | } else { 100 | XBMC->Log(ADDON::LOG_DEBUG, "Skipped - invalid reserve/ignore pattern rule: %d", i); 101 | continue; 102 | } 103 | 104 | std::string strGenreType = "none"; 105 | if (p["categories"].is()){ 106 | if (p["categories"].get().size() == 1) { 107 | strGenreType = p["categories"].get()[0].get(); 108 | rule.iGenreType = chinachu::iGenreTypePair[strGenreType] & chinachu::GENRE_TYPE_MASK; 109 | rule.iGenreSubType = chinachu::iGenreTypePair[strGenreType] & chinachu::GENRE_SUBTYPE_MASK; 110 | } else if (p["categories"].get().size() > 1){ 111 | strGenreType = "any"; 112 | } 113 | } 114 | int startTime = 0; 115 | int endTime = 24; 116 | if (p["hour"].is()) { 117 | startTime = p["hour"].get()["start"].is() ? (int)(p["hour"].get()["start"].get()) : 0; 118 | endTime = p["hour"].get()["end"].is() ? (int)(p["hour"].get()["end"].get()) : 0; 119 | } 120 | 121 | char title[PVR_ADDON_NAME_STRING_LENGTH]; 122 | snprintf(title, PVR_ADDON_NAME_STRING_LENGTH - 1, "#%d: [%s]%d-%d %s", i, strGenreType.c_str(), startTime, endTime, rule.strEpgSearchString.c_str()); 123 | rule.strTitle = title; 124 | 125 | if (p["channels"].is() && p["channels"].get().size() == 1) { 126 | char *endptr; 127 | rule.iClientChannelUid = strtoul(p["channels"].get()[0].get().c_str(), &endptr, 36) % 100000; 128 | } 129 | 130 | rule.bIsDisabled = (p["isDisabled"].is() && p["isDisabled"].get()); 131 | rule.state = rule.bIsDisabled ? PVR_TIMER_STATE_DISABLED : PVR_TIMER_STATE_SCHEDULED; 132 | 133 | rules.push_back(rule); 134 | } 135 | 136 | XBMC->Log(ADDON::LOG_NOTICE, "Updated rules: ammount = %d", rules.size()); 137 | 138 | return true; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/chinachu/rules.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_RULES_H 23 | #define CHINACHU_RULES_H 24 | #include 25 | 26 | #include "picojson/picojson.h" 27 | #include "chinachu/genre.h" 28 | #include "kodi/xbmc_pvr_types.h" 29 | 30 | namespace chinachu { 31 | struct RULE_ITEM { 32 | unsigned int iIndex; 33 | std::string strTitle; 34 | std::string strEpgSearchString; 35 | unsigned int iClientChannelUid; 36 | PVR_TIMER_STATE state; 37 | bool bFullTextEpgSearch; 38 | bool bIsDisabled; 39 | int iGenreType; 40 | int iGenreSubType; 41 | }; 42 | class Rule { 43 | public: 44 | std::vector rules; 45 | bool refresh(); 46 | }; 47 | } // namespace chinachu 48 | 49 | #endif /* end of include guard */ 50 | -------------------------------------------------------------------------------- /src/chinachu/schedule.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include "schedule.h" 23 | #include "api.h" 24 | #include "kodi/libXBMC_addon.h" 25 | 26 | extern ADDON::CHelper_libXBMC_addon *XBMC; 27 | 28 | namespace chinachu { 29 | bool Schedule::refresh() { 30 | picojson::value response; 31 | const time_t refreshInterval = 10*60; // every 10 minutes 32 | static time_t lastUpdated; 33 | time_t now; 34 | 35 | time(&now); 36 | if (now - lastUpdated < refreshInterval) { 37 | return true; 38 | } 39 | 40 | if (chinachu::api::getSchedule(response) == chinachu::api::REQUEST_FAILED) { 41 | return false; 42 | } 43 | 44 | schedule.clear(); 45 | channelGroups.clear(); 46 | 47 | for (picojson::value &a: response.get()) { 48 | picojson::object &o = a.get(); 49 | if (o["programs"].get().empty()) { 50 | continue; 51 | } 52 | 53 | PVR_CHANNEL ch; 54 | ch.iUniqueId = o["sid"].is() ? (int)(o["sid"].get()) : 0; 55 | ch.bIsRadio = false; 56 | ch.bIsHidden = false; 57 | ch.iChannelNumber = o["n"].is() ? (int)((o["n"].get())) + 1 : 0; 58 | ch.iSubChannelNumber = o["nid"].is() ? (int)(o["nid"].get()) : 0; 59 | // use channel id as name instead when name field isn't available. 60 | strncpy(ch.strChannelName, o["name"].is() ? o["name"].get().c_str() : o["id"].get().c_str(), PVR_ADDON_NAME_STRING_LENGTH - 1); 61 | 62 | if (o["hasLogoData"].get()) { 63 | snprintf(ch.strIconPath, PVR_ADDON_URL_STRING_LENGTH - 1, 64 | (const char*)(chinachu::api::baseURL + channelLogoPath).c_str(), 65 | o["id"].get().c_str()); 66 | } else { 67 | ch.strIconPath[0] = '\0'; 68 | } 69 | 70 | const std::string strChannelType = o["type"].get(); 71 | channelGroups[strChannelType].push_back(ch); 72 | 73 | for (picojson::value &ps: o["programs"].get()) { 74 | picojson::object &p = ps.get(); 75 | struct EPG_PROGRAM epg; 76 | char *endptr; 77 | 78 | epg.startTime = (time_t)(p["start"].get() / 1000); 79 | epg.endTime = (time_t)(p["end"].get() / 1000); 80 | epg.strUniqueBroadcastId = p["id"].get(); 81 | const std::string strSubstrId = epg.strUniqueBroadcastId.substr(epg.strUniqueBroadcastId.size() - 6, 6); 82 | epg.iUniqueBroadcastId = strtoul(strSubstrId.c_str(), &endptr, 36); 83 | epg.strTitle = p["title"].get(); 84 | epg.strEpisodeName = p["subTitle"].is() ? p["subTitle"].get() : ""; 85 | epg.strPlotOutline = p["description"].is() ? p["description"].get() : p["subTitle"].get(); 86 | epg.strPlot = p["detail"].is() ? p["detail"].get() : ""; 87 | epg.strOriginalTitle = p["fullTitle"].is() ? p["fullTitle"].get() : ""; 88 | epg.strGenreDescription = p["category"].is() ? p["category"].get() : ""; 89 | epg.iEpisodeNumber = p["episode"].is() ? (unsigned int)(p["episode"].get()) : 0; 90 | 91 | schedule[ch.iUniqueId].push_back(epg); 92 | } 93 | } 94 | 95 | XBMC->Log(ADDON::LOG_NOTICE, "Updated schedule: channel ammount = %d", schedule.size()); 96 | 97 | lastUpdated = now; 98 | return true; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/chinachu/schedule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #ifndef CHINACHU_SCHEDULE_H 23 | #define CHINACHU_SCHEDULE_H 24 | #include 25 | #include 26 | 27 | #include "picojson/picojson.h" 28 | #include "chinachu/genre.h" 29 | #include "kodi/xbmc_pvr_types.h" 30 | #include "kodi/xbmc_epg_types.h" 31 | 32 | namespace chinachu { 33 | struct EPG_PROGRAM { 34 | unsigned int iUniqueBroadcastId; 35 | unsigned int iEpisodeNumber; 36 | time_t startTime; 37 | time_t endTime; 38 | std::string strUniqueBroadcastId; 39 | std::string strTitle; 40 | std::string strPlotOutline; 41 | std::string strPlot; 42 | std::string strOriginalTitle; 43 | std::string strEpisodeName; 44 | std::string strGenreDescription; 45 | }; 46 | class Schedule { 47 | public: 48 | std::string channelLogoPath; 49 | std::string liveStreamingPath; 50 | std::map> schedule; 51 | std::map> channelGroups; 52 | bool refresh(); 53 | }; 54 | } // namespace chinachu 55 | 56 | #endif /* end of include guard */ 57 | -------------------------------------------------------------------------------- /src/pvr_client/Makefile.am: -------------------------------------------------------------------------------- 1 | LIB = ../$(ADDONNAME) 2 | 3 | lib_LTLIBRARIES = libpvrchinachu.la 4 | 5 | libpvrchinachu_la_SOURCES = \ 6 | channel.cpp \ 7 | demux.cpp \ 8 | information.cpp \ 9 | initialize.cpp \ 10 | live.cpp \ 11 | recording.cpp \ 12 | stream.cpp \ 13 | timer.cpp 14 | 15 | libpvrchinachu_la_LIBADD = \ 16 | ../chinachu/libchinachu.la 17 | 18 | libpvrchinachu_la_LDFLAGS = \ 19 | $(LDFLAGS_EXT) \ 20 | -avoid-version 21 | 22 | AM_CPPFLAGS = \ 23 | $(AM_CPPFLAGS_EXT) \ 24 | -std=c++11 \ 25 | -I. \ 26 | -I$(top_srcdir)/include -I$(top_srcdir)/src 27 | 28 | EXTRA_DIST = \ 29 | include 30 | 31 | $(ADDONNAME): libpvrchinachu.la 32 | cp -f .libs/libpvrchinachu.$(LIBEXT) $(ADDONNAME) 33 | 34 | $(LIB): $(ADDONNAME) 35 | cp -f $(ADDONNAME) $(LIB) 36 | 37 | all: $(LIB) 38 | 39 | clean-local: 40 | rm -f $(ADDONNAME) 41 | -------------------------------------------------------------------------------- /src/pvr_client/channel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include 23 | #include "kodi/libKODI_guilib.h" 24 | #include "kodi/libXBMC_addon.h" 25 | #include "kodi/libXBMC_pvr.h" 26 | #include "chinachu/chinachu.h" 27 | 28 | extern chinachu::Schedule g_schedule; 29 | extern ADDON::CHelper_libXBMC_addon *XBMC; 30 | extern CHelper_libXBMC_pvr *PVR; 31 | 32 | extern "C" { 33 | 34 | int GetChannelsAmount(void) { 35 | return g_schedule.schedule.size(); 36 | } 37 | 38 | PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio) { 39 | if (bRadio) { 40 | return PVR_ERROR_NO_ERROR; 41 | } 42 | 43 | if (!g_schedule.refresh()) { 44 | return PVR_ERROR_SERVER_ERROR; 45 | } 46 | 47 | for (const std::pair> schedule: g_schedule.channelGroups) { 48 | for (const PVR_CHANNEL channel: schedule.second) { 49 | PVR->TransferChannelEntry(handle, &channel); 50 | } 51 | } 52 | 53 | return PVR_ERROR_NO_ERROR; 54 | } 55 | 56 | int GetChannelGroupsAmount(void) { 57 | return g_schedule.channelGroups.size(); 58 | } 59 | 60 | PVR_ERROR GetChannelGroups(ADDON_HANDLE handle, bool bRadio) { 61 | for (const std::pair> channelGroup: g_schedule.channelGroups) { 62 | PVR_CHANNEL_GROUP chGroup; 63 | memset(&chGroup, 0, sizeof(PVR_CHANNEL_GROUP)); 64 | 65 | strncpy(chGroup.strGroupName, channelGroup.first.c_str(), PVR_ADDON_NAME_STRING_LENGTH - 1); 66 | chGroup.bIsRadio = false; 67 | // chGroup.iPosition = 0; /* not implemented */ 68 | 69 | PVR->TransferChannelGroup(handle, &chGroup); 70 | } 71 | 72 | return PVR_ERROR_NO_ERROR; 73 | } 74 | 75 | PVR_ERROR GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP &group) { 76 | for (const PVR_CHANNEL channel: g_schedule.channelGroups[group.strGroupName]) { 77 | PVR_CHANNEL_GROUP_MEMBER chMem; 78 | memset(&chMem, 0, sizeof(PVR_CHANNEL_GROUP_MEMBER)); 79 | 80 | chMem.iChannelUniqueId = channel.iUniqueId; 81 | chMem.iChannelNumber = channel.iChannelNumber; 82 | strncpy(chMem.strGroupName, group.strGroupName, PVR_ADDON_NAME_STRING_LENGTH - 1); 83 | 84 | PVR->TransferChannelGroupMember(handle, &chMem); 85 | } 86 | 87 | return PVR_ERROR_NO_ERROR; 88 | } 89 | 90 | /* not implemented */ 91 | PVR_ERROR OpenDialogChannelScan(void) { return PVR_ERROR_NOT_IMPLEMENTED; } 92 | PVR_ERROR DeleteChannel(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } 93 | PVR_ERROR RenameChannel(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } 94 | PVR_ERROR OpenDialogChannelSettings(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } 95 | PVR_ERROR OpenDialogChannelAdd(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } 96 | PVR_ERROR SetEPGTimeFrame(int iDays) { return PVR_ERROR_NOT_IMPLEMENTED; } 97 | PVR_ERROR GetChannelStreamProperties(const PVR_CHANNEL* channel, PVR_NAMED_VALUE* properties, unsigned int* iPropertiesCount) { return PVR_ERROR_NOT_IMPLEMENTED; } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/pvr_client/demux.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include 23 | #include "kodi/libKODI_guilib.h" 24 | #include "kodi/libXBMC_addon.h" 25 | #include "kodi/libXBMC_pvr.h" 26 | 27 | extern ADDON::CHelper_libXBMC_addon *XBMC; 28 | extern CHelper_libXBMC_pvr *PVR; 29 | 30 | extern "C" { 31 | 32 | /* not implemented */ 33 | void DemuxReset(void) {} 34 | void DemuxFlush(void) {} 35 | void DemuxAbort(void) {} 36 | DemuxPacket* DemuxRead(void) { return NULL; } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/pvr_client/information.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include 23 | #include "kodi/libKODI_guilib.h" 24 | #include "kodi/libXBMC_addon.h" 25 | #include "kodi/libXBMC_pvr.h" 26 | 27 | extern ADDON::CHelper_libXBMC_addon *XBMC; 28 | extern CHelper_libXBMC_pvr *PVR; 29 | 30 | char serverUrl[1024]; 31 | 32 | extern "C" { 33 | 34 | PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES* pCapabilities) { 35 | pCapabilities->bSupportsEPG = true; 36 | pCapabilities->bSupportsTV = true; 37 | pCapabilities->bSupportsRadio = false; 38 | pCapabilities->bSupportsRecordings = true; 39 | pCapabilities->bSupportsRecordingsUndelete = false; 40 | pCapabilities->bSupportsTimers = true; 41 | pCapabilities->bSupportsChannelGroups = true; 42 | pCapabilities->bSupportsChannelScan = false; 43 | pCapabilities->bSupportsChannelSettings = false; 44 | pCapabilities->bHandlesInputStream = false; 45 | pCapabilities->bHandlesDemuxing = false; 46 | pCapabilities->bSupportsRecordingPlayCount = false; 47 | pCapabilities->bSupportsLastPlayedPosition = false; 48 | pCapabilities->bSupportsRecordingEdl = false; 49 | pCapabilities->bSupportsRecordingsRename = false; 50 | pCapabilities->bSupportsRecordingsLifetimeChange = false; 51 | pCapabilities->bSupportsDescrambleInfo = false; 52 | pCapabilities->iRecordingsLifetimesSize = 0; 53 | 54 | return PVR_ERROR_NO_ERROR; 55 | } 56 | 57 | const char* GetConnectionString(void) { 58 | if (XBMC->GetSetting("server_url", &serverUrl)) { 59 | return serverUrl; 60 | } 61 | 62 | return ""; 63 | } 64 | 65 | const char* GetBackendName(void) { 66 | return "Chinachu"; 67 | } 68 | 69 | const char* GetBackendVersion(void) { 70 | return "gamma"; 71 | } 72 | 73 | const char* GetBackendHostname(void) { 74 | return ""; 75 | } 76 | 77 | /* not implemented */ 78 | PVR_ERROR GetDescrambleInfo(PVR_DESCRAMBLE_INFO* descrambleInfo) { return PVR_ERROR_NOT_IMPLEMENTED; } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/pvr_client/live.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include 23 | #include "kodi/libKODI_guilib.h" 24 | #include "kodi/libXBMC_addon.h" 25 | #include "kodi/libXBMC_pvr.h" 26 | #include "chinachu/chinachu.h" 27 | 28 | extern chinachu::Schedule g_schedule; 29 | extern ADDON::CHelper_libXBMC_addon *XBMC; 30 | extern CHelper_libXBMC_pvr *PVR; 31 | 32 | extern "C" { 33 | 34 | PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL &channel, time_t iStart, time_t iEnd) { 35 | for (const chinachu::EPG_PROGRAM epg: g_schedule.schedule[channel.iUniqueId]) { 36 | if (epg.endTime < iStart) continue; 37 | if (epg.startTime > iEnd) break; 38 | 39 | EPG_TAG tag; 40 | memset(&tag, 0, sizeof(EPG_TAG)); 41 | 42 | tag.iUniqueBroadcastId = epg.iUniqueBroadcastId; 43 | tag.strTitle = epg.strTitle.c_str(); 44 | tag.strOriginalTitle = epg.strOriginalTitle.c_str(); 45 | tag.iUniqueChannelId = channel.iUniqueId; 46 | tag.startTime = epg.startTime; 47 | tag.endTime = epg.endTime; 48 | tag.strPlotOutline = epg.strPlotOutline.c_str(); 49 | tag.strPlot = epg.strPlot.c_str(); 50 | tag.iGenreType = chinachu::iGenreTypePair[epg.strGenreDescription] & chinachu::GENRE_TYPE_MASK; 51 | tag.iGenreSubType = chinachu::iGenreTypePair[epg.strGenreDescription] & chinachu::GENRE_SUBTYPE_MASK; 52 | tag.iEpisodeNumber = epg.iEpisodeNumber; 53 | tag.strEpisodeName = epg.strEpisodeName.c_str(); 54 | tag.strGenreDescription = epg.strGenreDescription.c_str(); 55 | 56 | PVR->TransferEpgEntry(handle, &tag); 57 | } 58 | 59 | return PVR_ERROR_NO_ERROR; 60 | } 61 | 62 | PVR_ERROR IsEPGTagRecordable(const EPG_TAG* tag, bool* bIsRecordable) { 63 | *bIsRecordable = true; 64 | return PVR_ERROR_NO_ERROR; 65 | } 66 | 67 | PVR_ERROR IsEPGTagPlayable(const EPG_TAG* tag, bool* bIsPlayable) { 68 | *bIsPlayable = true; 69 | return PVR_ERROR_NO_ERROR; 70 | } 71 | 72 | void* liveStreamHandle = NULL; 73 | bool OpenLiveStream(const PVR_CHANNEL &channel) { 74 | std::string sId = ""; 75 | for (unsigned long iId = channel.iSubChannelNumber * 100000 + channel.iUniqueId; iId > 0; iId /= 36) { 76 | const int i = iId % 36; 77 | const char c = i < 10 ? '0' + i : 'a' + i - 10; 78 | sId = c + sId; 79 | } 80 | char url[1024]; 81 | snprintf(url, sizeof(url) - 1, (const char*)(chinachu::api::baseURL + g_schedule.liveStreamingPath).c_str(), sId.c_str()); 82 | liveStreamHandle = XBMC->OpenFile(url, 0); 83 | return liveStreamHandle != NULL; 84 | } 85 | 86 | void CloseLiveStream(void) { 87 | if (liveStreamHandle != NULL) 88 | XBMC->CloseFile(liveStreamHandle); 89 | liveStreamHandle = NULL; 90 | } 91 | 92 | int ReadLiveStream(unsigned char *pBuffer, unsigned int iBufferSize) { 93 | return XBMC->ReadFile(liveStreamHandle, pBuffer, iBufferSize); 94 | } 95 | 96 | bool IsRealTimeStream() { 97 | return true; 98 | } 99 | 100 | /* not implemented */ 101 | PVR_ERROR GetEPGTagStreamProperties(const EPG_TAG* tag, PVR_NAMED_VALUE* properties, unsigned int* iPropertiesCount) { return PVR_ERROR_NOT_IMPLEMENTED; } 102 | PVR_ERROR GetEPGTagEdl(const EPG_TAG* epgTag, PVR_EDL_ENTRY edl[], int *size) { return PVR_ERROR_NOT_IMPLEMENTED; }; 103 | long long SeekLiveStream(long long iPosition, int iWhence) { return -1; } 104 | long long LengthLiveStream(void) { return -1; } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/pvr_client/recording.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include 23 | #include 24 | #include "kodi/libKODI_guilib.h" 25 | #include "kodi/libXBMC_addon.h" 26 | #include "kodi/libXBMC_pvr.h" 27 | #include "chinachu/chinachu.h" 28 | 29 | #if defined(_WIN32) || defined(_WIN64) 30 | #include 31 | #define sleep(sec) Sleep(sec) 32 | #else 33 | #include 34 | #endif 35 | 36 | extern chinachu::Recorded g_recorded; 37 | extern ADDON::CHelper_libXBMC_addon *XBMC; 38 | extern CHelper_libXBMC_pvr *PVR; 39 | 40 | extern "C" { 41 | 42 | int GetRecordingsAmount(bool deleted) { 43 | return g_recorded.programs.size(); 44 | } 45 | 46 | PVR_ERROR GetRecordings(ADDON_HANDLE handle, bool deleted) { 47 | if (g_recorded.refresh()) { 48 | for (const PVR_RECORDING rec: g_recorded.programs) { 49 | PVR->TransferRecordingEntry(handle, &rec); 50 | } 51 | return PVR_ERROR_NO_ERROR; 52 | } 53 | return PVR_ERROR_SERVER_ERROR; 54 | } 55 | 56 | PVR_ERROR GetRecordingStreamProperties(const PVR_RECORDING* recording, PVR_NAMED_VALUE* properties, unsigned int* iPropertiesCount) { 57 | strncpy(properties[0].strName, PVR_STREAM_PROPERTY_STREAMURL, sizeof(properties[0].strName) - 1); 58 | snprintf(properties[0].strValue, sizeof(properties[0].strValue) - 1, (const char*)(chinachu::api::baseURL + g_recorded.recordedStreamingPath).c_str(), recording->strRecordingId); 59 | *iPropertiesCount = 1; 60 | return PVR_ERROR_NO_ERROR; 61 | } 62 | 63 | PVR_ERROR DeleteRecording(const PVR_RECORDING &recording) { 64 | if (chinachu::api::deleteRecordedProgram(recording.strRecordingId) != chinachu::api::REQUEST_FAILED) { 65 | XBMC->Log(ADDON::LOG_NOTICE, "Delete recording: %s", recording.strRecordingId); 66 | sleep(1); 67 | PVR->TriggerRecordingUpdate(); 68 | return PVR_ERROR_NO_ERROR; 69 | } 70 | return PVR_ERROR_SERVER_ERROR; 71 | } 72 | 73 | PVR_ERROR GetDriveSpace(long long *iTotal, long long *iUsed) { 74 | picojson::value response; 75 | const time_t refreshInterval = 10*60; // every 10 minutes 76 | static time_t lastUpdated; 77 | static long long total, used; 78 | 79 | time_t now; 80 | time(&now); 81 | 82 | if (now - lastUpdated < refreshInterval) { 83 | *iTotal = total; 84 | *iUsed = used; 85 | return PVR_ERROR_NO_ERROR; 86 | } 87 | 88 | if (chinachu::api::getStorage(response) == chinachu::api::REQUEST_FAILED) { 89 | return PVR_ERROR_SERVER_ERROR; 90 | } 91 | 92 | picojson::object &o = response.get(); 93 | total = (long long)(o["size"].get() / 1024); 94 | used = (long long)(o["used"].get() / 1024); 95 | *iTotal = total; 96 | *iUsed = used; 97 | 98 | lastUpdated = now; 99 | return PVR_ERROR_NO_ERROR; 100 | } 101 | 102 | /* not implemented */ 103 | PVR_ERROR UndeleteRecording(const PVR_RECORDING& recording) { return PVR_ERROR_NOT_IMPLEMENTED; } 104 | PVR_ERROR DeleteAllRecordingsFromTrash(void) { return PVR_ERROR_NOT_IMPLEMENTED; } 105 | PVR_ERROR RenameRecording(const PVR_RECORDING &recording) { return PVR_ERROR_NOT_IMPLEMENTED; } 106 | PVR_ERROR SetRecordingLifetime(const PVR_RECORDING* recording) { return PVR_ERROR_NOT_IMPLEMENTED; } 107 | PVR_ERROR SetRecordingPlayCount(const PVR_RECORDING &recording, int count) { return PVR_ERROR_NOT_IMPLEMENTED; } 108 | PVR_ERROR SetRecordingLastPlayedPosition(const PVR_RECORDING &recording, int lastplayedposition) { return PVR_ERROR_NOT_IMPLEMENTED; } 109 | int GetRecordingLastPlayedPosition(const PVR_RECORDING &recording) { return -1; } 110 | PVR_ERROR GetRecordingEdl(const PVR_RECORDING&, PVR_EDL_ENTRY[], int*) { return PVR_ERROR_NOT_IMPLEMENTED; }; 111 | bool OpenRecordedStream(const PVR_RECORDING &recording) { return false; } 112 | void CloseRecordedStream(void) {} 113 | int ReadRecordedStream(unsigned char *pBuffer, unsigned int iBufferSize) { return 0; } 114 | long long SeekRecordedStream(long long iPosition, int iWhence) { return 0; } 115 | long long LengthRecordedStream(void) { return 0; } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/pvr_client/stream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2018 Yuki MIZUNO 3 | * https://github.com/Harekaze/pvr.chinachu/ 4 | * 5 | * 6 | * This file is part of pvr.chinachu. 7 | * 8 | * pvr.chinachu is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pvr.chinachu is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with pvr.chinachu. If not, see . 20 | * 21 | */ 22 | #include 23 | #include "kodi/libKODI_guilib.h" 24 | #include "kodi/libXBMC_addon.h" 25 | #include "kodi/libXBMC_pvr.h" 26 | 27 | extern ADDON::CHelper_libXBMC_addon *XBMC; 28 | extern CHelper_libXBMC_pvr *PVR; 29 | 30 | extern "C" { 31 | 32 | bool CanPauseStream(void) { 33 | return true; 34 | } 35 | 36 | /* not implemented */ 37 | PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS &signalStatus) { return PVR_ERROR_NOT_IMPLEMENTED; } 38 | PVR_ERROR GetStreamProperties(PVR_STREAM_PROPERTIES *pProperties) { return PVR_ERROR_NOT_IMPLEMENTED; } 39 | PVR_ERROR GetStreamReadChunkSize(int* chunksize) { return PVR_ERROR_NOT_IMPLEMENTED; }; 40 | void PauseStream(bool bPaused) {} 41 | bool CanSeekStream(void) { return false; } 42 | bool SeekTime(int time, bool backwards, double *startpts) { return false; } 43 | void SetSpeed(int speed) {} 44 | 45 | } 46 | -------------------------------------------------------------------------------- /template/pvr.chinachu/addon.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | linux osx ios android rbpi windx 20 | GPL v3.0 21 | Chinachu PVR client 22 | https://github.com/Harekaze/pvr.chinachu/ 23 | https://github.com/Harekaze/pvr.chinachu/wiki 24 | https://github.com/Harekaze/pvr.chinachu/issues 25 | en ja 26 | Chinachu PVR client for Kodi 27 | 28 | 29 | -------------------------------------------------------------------------------- /template/pvr.chinachu/fanart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Harekaze/pvr.chinachu/2b12d3fc5460cdc95e19763a567647113f0e807d/template/pvr.chinachu/fanart.png -------------------------------------------------------------------------------- /template/pvr.chinachu/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Harekaze/pvr.chinachu/2b12d3fc5460cdc95e19763a567647113f0e807d/template/pvr.chinachu/icon.png -------------------------------------------------------------------------------- /template/pvr.chinachu/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Harekaze/pvr.chinachu/2b12d3fc5460cdc95e19763a567647113f0e807d/template/pvr.chinachu/icon@2x.png -------------------------------------------------------------------------------- /template/pvr.chinachu/resources/language/English/strings.po: -------------------------------------------------------------------------------- 1 | # Kodi Media Center language file 2 | # Addon Name: Harekaze (Chinachu PVR client) 3 | # Addon id: pvr.chinachu 4 | # Addon Provider: Harekaze project 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Kodi-Addons\n" 8 | "Report-Msgid-Bugs-To: https://github.com/Harekaze/pvr.chinachu/issues\n" 9 | "POT-Creation-Date: 2015-02-23 08:11+0000\n" 10 | "PO-Revision-Date: 2017-02-03 22:55+0900\n" 11 | "Last-Translator: Yuki MIZUNO \n" 12 | "Language-Team: LANGUAGE\n" 13 | "MIME-Version: 1.0\n" 14 | "Content-Type: text/plain; charset=UTF-8\n" 15 | "Content-Transfer-Encoding: 8bit\n" 16 | "Language: en\n" 17 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 18 | 19 | #Plugin settings strings 20 | 21 | msgctxt "#30200" 22 | msgid "General" 23 | msgstr "" 24 | 25 | msgctxt "#30201" 26 | msgid "Chinachu WUI URL" 27 | msgstr "" 28 | 29 | msgctxt "#30202" 30 | msgid "Mirakurun URL (optional)" 31 | msgstr "" 32 | 33 | #empty strings from id 30203 to 30299 34 | 35 | msgctxt "#30300" 36 | msgid "Streaming" 37 | msgstr "" 38 | 39 | msgctxt "#30301" 40 | msgid "Transcode video" 41 | msgstr "" 42 | 43 | msgctxt "#30302" 44 | msgid "Transcode audio" 45 | msgstr "" 46 | 47 | #empty strings from id 30303 to 30309 48 | 49 | msgctxt "#30310" 50 | msgid "Video transcode options" 51 | msgstr "" 52 | 53 | #empty strings from id 30311 to 30319 54 | 55 | msgctxt "#30320" 56 | msgid "Audio transcode options" 57 | msgstr "" 58 | 59 | #empty strings from id 30321 to 30330 60 | 61 | msgctxt "#30331" 62 | msgid "Codec" 63 | msgstr "" 64 | 65 | msgctxt "#30332" 66 | msgid "Bitrate(kbps)" 67 | msgstr "" 68 | 69 | msgctxt "#30333" 70 | msgid "Size" 71 | msgstr "" 72 | 73 | #empty strings from id 30334 to 30340 74 | 75 | msgctxt "#30341" 76 | msgid "H.264" 77 | msgstr "" 78 | 79 | msgctxt "#30342" 80 | msgid "MPEG-2" 81 | msgstr "" 82 | 83 | #empty strings from id 30343 to 30350 84 | 85 | msgctxt "#30351" 86 | msgid "AAC" 87 | msgstr "" 88 | 89 | msgctxt "#30352" 90 | msgid "Vorbis" 91 | msgstr "" 92 | 93 | #empty strings from id 30353 to 30399 94 | 95 | msgctxt "#30400" 96 | msgid "Recordings" 97 | msgstr "" 98 | 99 | msgctxt "#30401" 100 | msgid "Show thumbnail" 101 | msgstr "" 102 | 103 | msgctxt "#30402" 104 | msgid "Thumbnail position in seconds" 105 | msgstr "" 106 | 107 | #empty strings from id 30403 to 30499 108 | 109 | msgctxt "#30500" 110 | msgid "TV Guide" 111 | msgstr "" 112 | 113 | #empty strings from id 30501 to 30599 114 | 115 | msgctxt "#30600" 116 | msgid "Chinachu WUI URL starts with http:// or https://" 117 | msgstr "" 118 | 119 | #empty strings from id 30601 to 30799 120 | 121 | msgctxt "#30800" 122 | msgid "Refresh recordings" 123 | msgstr "" 124 | 125 | msgctxt "#30801" 126 | msgid "Refresh timers" 127 | msgstr "" 128 | 129 | msgctxt "#30802" 130 | msgid "Execute scheduler" 131 | msgstr "" 132 | 133 | #empty strings from id 30803 to 30899 134 | 135 | msgctxt "#30900" 136 | msgid "Manual Reserved" 137 | msgstr "" 138 | 139 | msgctxt "#30901" 140 | msgid "Pattern Matched" 141 | msgstr "" 142 | 143 | msgctxt "#30902" 144 | msgid "Pattern Match" 145 | msgstr "" 146 | 147 | msgctxt "#30903" 148 | msgid "Pattern Match" 149 | msgstr "" 150 | -------------------------------------------------------------------------------- /template/pvr.chinachu/resources/language/Japanese/strings.po: -------------------------------------------------------------------------------- 1 | # Kodi Media Center language file 2 | # Addon Name: Harekaze (Chinachu PVR client) 3 | # Addon id: pvr.chinachu 4 | # Addon Provider: Harekaze project 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Kodi-Addons\n" 8 | "Report-Msgid-Bugs-To: https://github.com/Harekaze/pvr.chinachu/issues\n" 9 | "POT-Creation-Date: 2015-02-23 08:11+0000\n" 10 | "PO-Revision-Date: 2017-02-03 22:55+0900\n" 11 | "Last-Translator: Yuki MIZUNO \n" 12 | "Language-Team: LANGUAGE\n" 13 | "MIME-Version: 1.0\n" 14 | "Content-Type: text/plain; charset=UTF-8\n" 15 | "Content-Transfer-Encoding: 8bit\n" 16 | "Language: ja\n" 17 | "Plural-Forms: nplurals=1; plural=0\n" 18 | 19 | msgctxt "#30200" 20 | msgid "General" 21 | msgstr "基本" 22 | 23 | msgctxt "#30201" 24 | msgid "Chinachu WUI URL" 25 | msgstr "Chinachu WUIのURL" 26 | 27 | msgctxt "#30202" 28 | msgid "Mirakurun URL (optional)" 29 | msgstr "MirakurunのURL (あれば)" 30 | 31 | msgctxt "#30300" 32 | msgid "Streaming" 33 | msgstr "ストリーミング" 34 | 35 | msgctxt "#30301" 36 | msgid "Transcode video" 37 | msgstr "映像エンコード" 38 | 39 | msgctxt "#30302" 40 | msgid "Transcode audio" 41 | msgstr "音声エンコード" 42 | 43 | msgctxt "#30310" 44 | msgid "Video transcode options" 45 | msgstr "映像エンコードオプション" 46 | 47 | msgctxt "#30320" 48 | msgid "Audio transcode options" 49 | msgstr "音声エンコードオプション" 50 | 51 | msgctxt "#30331" 52 | msgid "Codec" 53 | msgstr "コーデック" 54 | 55 | msgctxt "#30332" 56 | msgid "Bitrate(kbps)" 57 | msgstr "ビットレート(kbps)" 58 | 59 | msgctxt "#30333" 60 | msgid "Size" 61 | msgstr "サイズ" 62 | 63 | msgctxt "#30400" 64 | msgid "Recordings" 65 | msgstr "録画" 66 | 67 | msgctxt "#30401" 68 | msgid "Show thumbnail" 69 | msgstr "サムネイルを表示する" 70 | 71 | msgctxt "#30402" 72 | msgid "Thumbnail position in seconds" 73 | msgstr "サムネイルの位置(秒)" 74 | 75 | msgctxt "#30500" 76 | msgid "TV Guide" 77 | msgstr "番組表" 78 | 79 | msgctxt "#30600" 80 | msgid "Chinachu WUI URL starts with http:// or https://" 81 | msgstr "Chinachu WUIのURLは http:// か https:// を含めて入力してください" 82 | 83 | msgctxt "#30800" 84 | msgid "Refresh recordings" 85 | msgstr "録画一覧を更新" 86 | 87 | msgctxt "#30801" 88 | msgid "Refresh timers" 89 | msgstr "予約一覧を更新" 90 | 91 | msgctxt "#30802" 92 | msgid "Execute scheduler" 93 | msgstr "スケジューラーの実行" 94 | 95 | msgctxt "#30900" 96 | msgid "Manual Reserved" 97 | msgstr "手動予約" 98 | 99 | msgctxt "#30901" 100 | msgid "Pattern Matched" 101 | msgstr "ルール一致" 102 | 103 | msgctxt "#30902" 104 | msgid "Pattern Match" 105 | msgstr "ルール作成" 106 | 107 | msgctxt "#30903" 108 | msgid "Pattern Match" 109 | msgstr "ルール" 110 | -------------------------------------------------------------------------------- /template/pvr.chinachu/resources/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | --------------------------------------------------------------------------------