mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Windows compilation support (#738)
* Disable AVAHI * Replace SysInfo backport with Qt SysInfo * Update vscode config * Update LedDevices * Update Logger * Update hyperiond * Update hyperion-remote * Exclude avahi * Empty definition for Process * PythonInit path broken * Exclude PiBlaster and link ws2_32 * more avahi * resolve ui bug * Update Compile howto * JsonAPI QtGrabber missing * fix error * ssize_t replacement * Nope, doesn't work * Adjust compile description and verify winSDK * Update ci script * Update ci script * Update ci * Update ci script * update Logger * Update PythonInit * added Azure & GitHub Actions, Logger, PythonInit * resolve merge conflicts * revert ssize_t in FadeCandy * look at registry for QT5 & use find_package(Python) if cmake >= 3.12 * second try * another try * and yet another test * qt5 registry search undone * Package creation test * finished package creation. only fine tuning is required :-) Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Dependencies for Windows finished Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * use 'add_definitions()' until CMake 3.12 Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Update .github/workflows/pull-request.yml Co-Authored-By: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com> * Update cmake/Dependencies.cmake Co-Authored-By: brindosch <edeltraud70@gmx.de> * fix typo/ add VCINSTALLDIR var * fix again * Undo change again (Not working) * fix QT grabber Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * first NSIS test Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Update NSIS package * surprise :-) Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Update NSIS package * fix: NSIS .bmps * Add nsis templates * Force windows gui app * fix: QSysInfo required Qt5.6, now it's 5.4 again * Update: Remove platform component and adjust package name * Add macOS as system name * Update docs * fix: Allow gh actions ci also for forks with branches * Add ReadMe docs, mention windows, add vscode linux debug config * fix: readme visual * reduce/hide banner/copyright/log message Infos here: https://docs.microsoft.com/de-de/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2019#switches * Fix PythonInit * vscode: Add runner task * fix(vscode): compiler path gcc ver independent * fix azure * vscode: add windows run tasks * move process detection * main: add windows process detection * Azure file shredder * Update docs Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com> Co-authored-by: Paulchen-Panther <Paulchen-Panter@protonmail.com>
This commit is contained in:
		
							
								
								
									
										33
									
								
								.azure.yml
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								.azure.yml
									
									
									
									
									
								
							| @@ -61,4 +61,35 @@ jobs: | ||||
|     env: | ||||
|       PLATFORM: 'osx' | ||||
|     condition: succeeded() | ||||
|     displayName: 'Build macOS 10.13 packages' | ||||
|     displayName: 'Build macOS 10.13 packages' | ||||
|  | ||||
| ###################### | ||||
| ###### windows ####### | ||||
| ###################### | ||||
|  | ||||
| - job: windows | ||||
|   timeoutInMinutes: 120 | ||||
|   pool: | ||||
|     vmImage: 'windows-latest' | ||||
|  | ||||
|   steps: | ||||
|   - checkout: self # represents the repo where the initial Pipelines YAML file was found | ||||
|     submodules: recursive # set to 'recursive' to get submodules of submodules | ||||
|  | ||||
|   - task: UsePythonVersion@0 | ||||
|     inputs: | ||||
|       versionSpec: '3.x' | ||||
|       addToPath: true | ||||
|       architecture: 'x64' | ||||
|  | ||||
|   - script: | | ||||
|       cd $(Build.SourcesDirectory) | ||||
|       python -m pip install aqtinstall | ||||
|       python -m aqt install -O c:\Qt 5.14.0 windows desktop win64_msvc2017_64 | ||||
|     displayName: 'Install Qt 5.14.0' | ||||
|   # build process | ||||
|   - bash: ./.ci/ci_build.sh | ||||
|     env: | ||||
|       PLATFORM: 'windows' | ||||
|     condition: succeeded() | ||||
|     displayName: 'Build windows packages' | ||||
|   | ||||
| @@ -3,10 +3,12 @@ | ||||
| # detect CI | ||||
| if [ "$SYSTEM_COLLECTIONID" != "" ]; then | ||||
| 	# Azure Pipelines | ||||
| 	echo "Azure detected" | ||||
| 	CI_NAME="$(echo "$AGENT_OS" | tr '[:upper:]' '[:lower:]')" | ||||
| 	CI_BUILD_DIR="$BUILD_SOURCESDIRECTORY" | ||||
| elif [ "$HOME" != "" ]; then | ||||
| 	# GitHub Actions | ||||
| 	echo "Github Actions detected" | ||||
| 	CI_NAME="$(uname -s | tr '[:upper:]' '[:lower:]')" | ||||
| 	CI_BUILD_DIR="$GITHUB_WORKSPACE" | ||||
| else | ||||
| @@ -34,6 +36,15 @@ if [[ "$CI_NAME" == 'osx' || "$CI_NAME" == 'darwin' ]]; then | ||||
| 	cd ${CI_BUILD_DIR} && source /${CI_BUILD_DIR}/test/testrunner.sh || exit 4 | ||||
| 	exit 0; | ||||
| 	exit 1 || { echo "---> Hyperion compilation failed! Abort"; exit 5; } | ||||
| elif [[ $CI_NAME == *"mingw64_nt"* || "$CI_NAME" == 'windows_nt' ]]; then | ||||
| 	# compile prepare | ||||
| 	echo "Number of Cores $NUMBER_OF_PROCESSORS" | ||||
| 	mkdir build || exit 1 | ||||
| 	cd build | ||||
| 	cmake -G "Visual Studio 16 2019" -A x64 -DPLATFORM=${PLATFORM} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} ../ || exit 2 | ||||
| 	cmake --build . --target package --config Release -- -nologo -v:m -maxcpucount || exit 3 | ||||
| 	exit 0; | ||||
| 	exit 1 || { echo "---> Hyperion compilation failed! Abort"; exit 5; } | ||||
| elif [[ "$CI_NAME" == 'linux' ]]; then | ||||
| 	echo "Compile Hyperion with DOCKER_TAG = ${DOCKER_TAG} and friendly name DOCKER_NAME = ${DOCKER_NAME}" | ||||
| 	# take ownership of deploy dir | ||||
|   | ||||
| @@ -38,6 +38,11 @@ if [[ $CI_NAME == 'osx' || $CI_NAME == 'darwin' ]]; then | ||||
| 	brew update | ||||
| 	dependencies=("qt5" "python" "libusb" "cmake" "doxygen") | ||||
| 	installAndUpgrade "${dependencies[@]}" | ||||
| # github actions uname -> windows-2019 -> mingw64_nt-10.0-17763 | ||||
| # TODO: Azure uname windows? | ||||
| elif [[ $CI_NAME == *"mingw64_nt"* ]]; then | ||||
| 	echo "Yes, we are Windows: $CI_NAME" | ||||
| # Windows has no dependency manager | ||||
| elif [[ $CI_NAME != 'linux' ]]; then | ||||
| 	echo "Unsupported platform: $CI_NAME" | ||||
| 	exit 5 | ||||
|   | ||||
							
								
								
									
										62
									
								
								.github/workflows/pull-request.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								.github/workflows/pull-request.yml
									
									
									
									
										vendored
									
									
								
							| @@ -114,6 +114,68 @@ jobs: | ||||
|           name: macOS.zip | ||||
|           path: macOS | ||||
|  | ||||
| ###################### | ||||
| ###### Windows ####### | ||||
| ###################### | ||||
|  | ||||
|   windows: | ||||
|     name: Windows | ||||
|     runs-on: windows-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v1 | ||||
|         with: | ||||
|           submodules: true | ||||
|  | ||||
|       # Append PR number to version | ||||
|       - name: Append PR number to version | ||||
|         shell: bash | ||||
|         run: | | ||||
|           tr -d '\n' < version > temp && mv temp version | ||||
|           echo -n "-PR#${{ github.event.pull_request.number }}" >> version | ||||
|  | ||||
|       - name: Install Qt | ||||
|         uses: jurplel/install-qt-action@v2 | ||||
|         with: | ||||
|           version: '5.14.1' | ||||
|           target: 'desktop' | ||||
|           arch: 'win64_msvc2017_64' | ||||
|  | ||||
|       - name: Install Python | ||||
|         uses: actions/setup-python@v1 | ||||
|         with: | ||||
|           python-version: '3.x' | ||||
|  | ||||
|       - name: Install NSIS | ||||
|         run: | | ||||
|           Invoke-WebRequest https://netcologne.dl.sourceforge.net/project/nsis/NSIS%203/3.05/nsis-3.05-setup.exe -OutFile nsis-setup.exe | ||||
|           .\nsis-setup.exe /S | ||||
|  | ||||
|       - name: Set up x64 build architecture environment | ||||
|         shell: cmd | ||||
|         run: call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" | ||||
|  | ||||
|       # Build packages | ||||
|       - name: Build packages | ||||
|         env: | ||||
|           VCINSTALLDIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC' | ||||
|           PLATFORM: windows | ||||
|         shell: bash | ||||
|         run: ./.ci/ci_build.sh | ||||
|  | ||||
|       # Collecting deployable artifacts | ||||
|       - name: Collecting deployable artifacts | ||||
|         shell: bash | ||||
|         run: | | ||||
|           mkdir -p windows | ||||
|           mv build/*.zip windows | ||||
|       # Upload artifacts | ||||
|       - name: Upload artifacts | ||||
|         uses: actions/upload-artifact@v1 | ||||
|         with: | ||||
|           name: windows.zip | ||||
|           path: windows | ||||
|  | ||||
| ###################### | ||||
| #### Documentation ### | ||||
| ###################### | ||||
|   | ||||
							
								
								
									
										36
									
								
								.github/workflows/push-master.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								.github/workflows/push-master.yml
									
									
									
									
										vendored
									
									
								
							| @@ -85,6 +85,42 @@ jobs: | ||||
|         with: | ||||
|           path: build/Hyperion-* | ||||
|  | ||||
| ###################### | ||||
| ###### Windows ####### | ||||
| ###################### | ||||
|  | ||||
|   windows: | ||||
|     name: Windows | ||||
|     runs-on: windows-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v1 | ||||
|         with: | ||||
|           submodules: true | ||||
|  | ||||
|       - name: Install Qt | ||||
|         uses: jurplel/install-qt-action@v2 | ||||
|         with: | ||||
|           version: '5.14.1' | ||||
|           target: 'desktop' | ||||
|           arch: 'win64_msvc2017_64' | ||||
|  | ||||
|       - name: Install Python | ||||
|         uses: actions/setup-python@v1 | ||||
|         with: | ||||
|           python-version: '3.x' | ||||
|  | ||||
|       - name: Set up x64 build architecture environment | ||||
|         shell: cmd | ||||
|         run: call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" | ||||
|  | ||||
|       # Build packages | ||||
|       - name: Build packages | ||||
|         env: | ||||
|           PLATFORM: windows | ||||
|         shell: bash | ||||
|         run: ./.ci/ci_build.sh | ||||
|  | ||||
| ###################### | ||||
| #### Documentation ### | ||||
| ###################### | ||||
|   | ||||
							
								
								
									
										20
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							| @@ -7,12 +7,28 @@ | ||||
|                 "/usr/include/**" | ||||
|             ], | ||||
|             "defines": [], | ||||
|             "compilerPath": "/usr/bin/gcc-5", | ||||
|             "compilerPath": "/usr/bin/gcc", | ||||
|             "intelliSenseMode": "gcc-x64", | ||||
|             "cppStandard": "c++11", | ||||
|             "cStandard": "c11", | ||||
|             "configurationProvider": "ms-vscode.cmake-tools" | ||||
|         }, | ||||
|         { | ||||
|             "name": "Win32", | ||||
|             "includePath": [ | ||||
|                 "${workspaceFolder}/**", | ||||
|                 "G:/Programme/Qt/5.14.1/msvc2017_64/include/**" | ||||
|             ], | ||||
|             "defines": [ | ||||
|                 "_DEBUG", | ||||
|                 "UNICODE", | ||||
|                 "_UNICODE" | ||||
|             ], | ||||
|             "cStandard": "c11", | ||||
|             "cppStandard": "c++11", | ||||
|             "intelliSenseMode": "msvc-x64", | ||||
|             "configurationProvider": "ms-vscode.cmake-tools" | ||||
|         } | ||||
|     ], | ||||
|     "version": 4 | ||||
| } | ||||
| } | ||||
|   | ||||
							
								
								
									
										28
									
								
								.vscode/hyperion.code-workspace
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								.vscode/hyperion.code-workspace
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| { | ||||
| 	"folders": [ | ||||
| 		{ | ||||
| 			"path": "../" | ||||
| 		} | ||||
| 	], | ||||
| 	"settings": { | ||||
| 		"editor.formatOnSave": false, | ||||
| 		"cmake.environment": { | ||||
| 			"Qt5_DIR":"G:/Programme/Qt/5.14.1/msvc2017_64/lib/cmake/Qt5", | ||||
| 			"CMAKE_PREFIX_PATH": "G:/Programme/Qt/5.14.1/msvc2017_64" | ||||
| 		}, | ||||
| 	}, | ||||
| 	"extensions": { | ||||
| 		"recommendations": [ | ||||
| 			"twxs.cmake", | ||||
| 			"ms-vscode.cpptools", | ||||
| 			"ms-vscode.cmake-tools", | ||||
| 			"spmeesseman.vscode-taskexplorer", | ||||
| 			"yzhang.markdown-all-in-one", | ||||
| 			"formulahendry.auto-rename-tag", | ||||
| 			"CoenraadS.bracket-pair-colorizer", | ||||
| 			"eamodio.gitlens", | ||||
| 			"vscode-icons-team.vscode-icons", | ||||
| 			"editorconfig.editorconfig" | ||||
| 		] | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										38
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| { | ||||
|   // Use IntelliSense to learn about possible attributes. | ||||
|   // Hover to view descriptions of existing attributes. | ||||
|   // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||||
|   "version": "0.2.0", | ||||
|   "configurations": [ | ||||
|     { | ||||
|       "name": "(Linux) hyperiond", | ||||
|       "type": "cppdbg", | ||||
|       "request": "launch", | ||||
|       "program": "${workspaceFolder}/build/bin/hyperiond", | ||||
|       "args": [], | ||||
|       "stopAtEntry": false, | ||||
|       "cwd": "${workspaceFolder}", | ||||
|       "environment": [], | ||||
|       "externalConsole": false, | ||||
|       "MIMode": "gdb", | ||||
|       "setupCommands": [ | ||||
|         { | ||||
|           "description": "Enable pretty-printing for gdb", | ||||
|           "text": "-enable-pretty-printing", | ||||
|           "ignoreFailures": true | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "name": "(Windows) hyperiond", | ||||
|       "type": "cppvsdbg", | ||||
|       "request": "launch", | ||||
|       "program": "${workspaceFolder}/build/bin/hyperiond.exe", | ||||
|       "args": [], | ||||
|       "stopAtEntry": false, | ||||
|       "cwd": "${workspaceFolder}", | ||||
|       "environment": [], | ||||
|       "externalConsole": false | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										123
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | ||||
| { | ||||
|   // See https://go.microsoft.com/fwlink/?LinkId=733558 | ||||
|   // for the documentation about the tasks.json format | ||||
|   "version": "2.0.0", | ||||
|   "tasks": [ | ||||
|     { | ||||
|       "label": "cmake:conf Release", | ||||
|       "detail": "Configure Build Env. Release/Debug switch not required for multi generators (msvc)", | ||||
|       "type": "shell", | ||||
|       "command": "cmake -B ${workspaceFolder}/build -DCMAKE_BUILD_TYPE=Release", | ||||
|       "windows": { | ||||
|         "command": "cmake -G \"Visual Studio 16 2019\" -A x64 -B ${workspaceFolder}/build" | ||||
|       }, | ||||
|       "group": "build", | ||||
|     }, | ||||
|     { | ||||
|       "label": "cmake:conf Debug", | ||||
|       "detail": "Configure Build Env. Release/Debug switch not required with msvc", | ||||
|       "type": "shell", | ||||
|       "command": "cmake -B ${workspaceFolder}/build -DCMAKE_BUILD_TYPE=Debug", | ||||
|       "windows": { | ||||
|         "command": "cmake -G \"Visual Studio 16 2019\" -A x64 -B ${workspaceFolder}/build" | ||||
|       }, | ||||
|       "group": "build", | ||||
|     }, | ||||
|     { | ||||
|       "label": "build:debug hyperiond", | ||||
|       "type": "shell", | ||||
|       "command": "cmake --build ${workspaceFolder}/build --target hyperiond -- -j $(nproc)", | ||||
|       "windows": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target hyperiond --config Debug -- -maxcpucount" | ||||
|       }, | ||||
|       "osx": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target hyperiond -- -j $(sysctl -n hw.ncpu)" | ||||
|       }, | ||||
|       "group": { | ||||
|         "kind": "build", | ||||
|         "isDefault": true | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "label": "build:debug all", | ||||
|       "type": "shell", | ||||
|       "command": "cmake --build ${workspaceFolder}/build -- -j $(nproc)", | ||||
|       "windows": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --config Debug -- -maxcpucount" | ||||
|       }, | ||||
|       "osx": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build -- -j $(sysctl -n hw.ncpu)" | ||||
|       }, | ||||
|       "group": "build" | ||||
|     }, | ||||
|     { | ||||
|       "label": "build:debug package", | ||||
|       "type": "shell", | ||||
|       "command": "cmake --build ${workspaceFolder}/build --target package -- -j $(nproc)", | ||||
|       "windows": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target package --config Debug -- -maxcpucount" | ||||
|       }, | ||||
|       "osx": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target package -- -j $(sysctl -n hw.ncpu)" | ||||
|       }, | ||||
|       "group": "build" | ||||
|     }, | ||||
|     { | ||||
|       "label": "build:release hyperiond", | ||||
|       "type": "shell", | ||||
|       "command": "cmake --build ${workspaceFolder}/build --target hyperiond -- -j $(nproc)", | ||||
|       "windows": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target hyperiond --config Release -- -maxcpucount" | ||||
|       }, | ||||
|       "osx": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target hyperiond -- -j $(sysctl -n hw.ncpu)" | ||||
|       }, | ||||
|       "group": { | ||||
|         "kind": "build", | ||||
|         "isDefault": true | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "label": "build:release all", | ||||
|       "type": "shell", | ||||
|       "command": "cmake --build ${workspaceFolder}/build -- -j $(nproc)", | ||||
|       "windows": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --config Release -- -maxcpucount" | ||||
|       }, | ||||
|       "osx": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build -- -j $(sysctl -n hw.ncpu)" | ||||
|       }, | ||||
|       "group": "build" | ||||
|     }, | ||||
|     { | ||||
|       "label": "build:release package", | ||||
|       "type": "shell", | ||||
|       "command": "cmake --build ${workspaceFolder}/build --target package -- -j $(nproc)", | ||||
|       "windows": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target package --config Release -- -maxcpucount" | ||||
|       }, | ||||
|       "osx": { | ||||
|         "command": "cmake --build ${workspaceFolder}/build --target package -- -j $(sysctl -n hw.ncpu)" | ||||
|       }, | ||||
|       "group": "build" | ||||
|     }, | ||||
|     { | ||||
|       "label": "run:hyperiond (Debug)", | ||||
|       "type": "shell", | ||||
|       "command": "${workspaceFolder}/build/bin/hyperiond -d", | ||||
|       "windows": { | ||||
|         "command": "${workspaceFolder}/build/bin/Debug/hyperiond" | ||||
|       }, | ||||
|       "group": "build" | ||||
|     }, | ||||
|     { | ||||
|       "label": "run:hyperiond (Release)", | ||||
|       "type": "shell", | ||||
|       "command": "${workspaceFolder}/build/bin/hyperiond -d", | ||||
|       "windows": { | ||||
|         "command": "${workspaceFolder}/build/bin/Release/hyperiond" | ||||
|       }, | ||||
|       "group": "build" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										103
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								CMakeLists.txt
									
									
									
									
									
								
							| @@ -25,8 +25,15 @@ if ( CCACHE_FOUND ) | ||||
| 	set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) | ||||
| endif(CCACHE_FOUND) | ||||
|  | ||||
| set(Python_ADDITIONAL_VERSIONS 3.5) | ||||
| find_package( PythonInterp 3.5 REQUIRED ) | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	find_package(Python3 COMPONENTS Interpreter Development REQUIRED) | ||||
| 	if(Python_FOUND) | ||||
| 		set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) | ||||
| 	endif() | ||||
| else() | ||||
| 	set(Python_ADDITIONAL_VERSIONS 3.5) | ||||
| 	find_package( PythonInterp 3.5 REQUIRED ) | ||||
| endif() | ||||
|  | ||||
| # Set build variables | ||||
| SET ( DEFAULT_AMLOGIC    OFF ) | ||||
| @@ -35,6 +42,7 @@ SET ( DEFAULT_OSX        OFF ) | ||||
| SET ( DEFAULT_X11        OFF ) | ||||
| SET ( DEFAULT_QT         ON ) | ||||
| SET ( DEFAULT_WS281XPWM  OFF ) | ||||
| SET ( DEFAULT_AVAHI      ON  ) | ||||
| SET ( DEFAULT_USE_SHARED_AVAHI_LIBS  ON ) | ||||
| SET ( DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS OFF ) | ||||
| SET ( DEFAULT_USE_SYSTEM_PROTO_LIBS OFF ) | ||||
| @@ -43,12 +51,14 @@ SET ( DEFAULT_TESTS      OFF ) | ||||
| IF ( ${CMAKE_SYSTEM} MATCHES "Linux" ) | ||||
| 	SET ( DEFAULT_V4L2   ON  ) | ||||
| 	SET ( DEFAULT_SPIDEV ON ) | ||||
| 	SET ( DEFAULT_TINKERFORGE ON) | ||||
| 	SET ( DEFAULT_FB     ON ) | ||||
| 	SET ( DEFAULT_USB_HID ON ) | ||||
| ELSE() | ||||
| 	SET ( DEFAULT_V4L2   OFF ) | ||||
| 	SET ( DEFAULT_FB     OFF ) | ||||
| 	SET ( DEFAULT_SPIDEV OFF ) | ||||
| 	SET ( DEFAULT_TINKERFORGE OFF) | ||||
| 	SET ( DEFAULT_USB_HID OFF ) | ||||
| ENDIF() | ||||
|  | ||||
| @@ -114,8 +124,8 @@ elseif ( "${PLATFORM}" MATCHES "x11" ) | ||||
| 	endif() | ||||
| elseif ( "${PLATFORM}" STREQUAL "imx6" ) | ||||
| 	SET ( DEFAULT_FB         ON ) | ||||
| elseif ( "${PLATFORM}" STREQUAL "windows" ) | ||||
| 	MESSAGE( WARNING "Hyperion is not developed nor tested on MS Windows.") | ||||
| elseif (WIN32) | ||||
| 	SET ( DEFAULT_AVAHI    OFF) | ||||
| endif() | ||||
|  | ||||
| # enable tests for -dev builds | ||||
| @@ -147,7 +157,7 @@ message(STATUS "ENABLE_OSX = ${ENABLE_OSX}") | ||||
| option(ENABLE_SPIDEV   "Enable the SPIDEV device" ${DEFAULT_SPIDEV} ) | ||||
| message(STATUS "ENABLE_SPIDEV   = ${ENABLE_SPIDEV}") | ||||
|  | ||||
| option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" ON) | ||||
| option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" ${DEFAULT_TINKERFORGE}) | ||||
| message(STATUS "ENABLE_TINKERFORGE = ${ENABLE_TINKERFORGE}") | ||||
|  | ||||
| option(ENABLE_V4L2 "Enable the V4L2 grabber" ${DEFAULT_V4L2}) | ||||
| @@ -156,6 +166,9 @@ message(STATUS "ENABLE_V4L2 = ${ENABLE_V4L2}") | ||||
| option(ENABLE_WS281XPWM "Enable the WS281x-PWM device" ${DEFAULT_WS281XPWM} ) | ||||
| message(STATUS "ENABLE_WS281XPWM = ${ENABLE_WS281XPWM}") | ||||
|  | ||||
| option(ENABLE_AVAHI "Enable Zeroconf" ${DEFAULT_AVAHI}) | ||||
| message(STATUS "ENABLE_AVAHI = " ${ENABLE_AVAHI}) | ||||
|  | ||||
| option(ENABLE_USB_HID "Enable the libusb and hid devices" ${DEFAULT_USB_HID} ) | ||||
| message(STATUS "ENABLE_USB_HID = ${ENABLE_USB_HID}") | ||||
|  | ||||
| @@ -183,6 +196,7 @@ SET( JSON_FILES | ||||
| 	config/hyperion.config.json.default | ||||
| 	${HYPERION_SCHEMAS} | ||||
| ) | ||||
|  | ||||
| EXECUTE_PROCESS ( | ||||
| 	COMMAND ${PYTHON_EXECUTABLE} test/jsonchecks/checkjson.py ${JSON_FILES} | ||||
| 	WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | ||||
| @@ -202,11 +216,14 @@ IF ( ${CHECK_EFFECTS_FAILED} ) | ||||
| ENDIF () | ||||
|  | ||||
| # for python 3 the checkschema.py file must be rewritten | ||||
| EXECUTE_PROCESS ( | ||||
| 	COMMAND python test/jsonchecks/checkschema.py config/hyperion.config.json.default libsrc/hyperion/hyperion.schema.json | ||||
| 	WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | ||||
| 	RESULT_VARIABLE CHECK_CONFIG_FAILED | ||||
| ) | ||||
| # TODO on windows it can't resolve the path inside the file (Das System kann den angegebenen Pfad nicht finden: '\\schema\\schema-general.json') | ||||
| IF (NOT WIN32) | ||||
| 	EXECUTE_PROCESS ( | ||||
| 		COMMAND python test/jsonchecks/checkschema.py config/hyperion.config.json.default libsrc/hyperion/hyperion.schema.json | ||||
| 		WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | ||||
| 		RESULT_VARIABLE CHECK_CONFIG_FAILED | ||||
| 	) | ||||
| ENDIF() | ||||
| IF ( ${CHECK_CONFIG_FAILED} ) | ||||
| 	MESSAGE (FATAL_ERROR "check of json default config failed" ) | ||||
| ENDIF () | ||||
| @@ -235,29 +252,61 @@ include_directories(${CMAKE_SOURCE_DIR}/include) | ||||
| # Prefer static linking over dynamic | ||||
| #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so") | ||||
|  | ||||
| # enable C++11 | ||||
| include(CheckCXXCompilerFlag) | ||||
| CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) | ||||
| CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) | ||||
| # enable C++11; MSVC doesn't have c++11 feature switch | ||||
| if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") | ||||
| 	include(CheckCXXCompilerFlag) | ||||
| 	CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) | ||||
| 	CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) | ||||
|  | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") | ||||
| if (CMAKE_COMPILER_IS_GNUCXX) | ||||
| 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi") | ||||
| 	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-psabi") | ||||
| 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") | ||||
| 	if (CMAKE_COMPILER_IS_GNUCXX) | ||||
| 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi") | ||||
| 		set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-psabi") | ||||
| 	endif() | ||||
| 	if(COMPILER_SUPPORTS_CXX11) | ||||
| 			set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | ||||
| 	elseif(COMPILER_SUPPORTS_CXX0X) | ||||
| 			set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") | ||||
| 	else() | ||||
| 			message(STATUS "No support for C++11 detected. Compilation will most likely fail on your compiler") | ||||
| 	endif() | ||||
| endif() | ||||
| if(COMPILER_SUPPORTS_CXX11) | ||||
|     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | ||||
| elseif(COMPILER_SUPPORTS_CXX0X) | ||||
|     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") | ||||
| else() | ||||
|     message(STATUS "No support for C++11 detected. Compilation will most likely fail on your compiler") | ||||
|  | ||||
| # MSVC options | ||||
| if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") | ||||
| 	# Search for Windows SDK | ||||
| 	find_package(WindowsSDK REQUIRED) | ||||
| 	message(STATUS "WINDOWS SDK: ${WINDOWSSDK_LATEST_DIR} ${WINDOWSSDK_LATEST_NAME}") | ||||
| 	message(STATUS "MSVC VERSION: ${MSVC_VERSION}") | ||||
|  | ||||
| 	# Qt5 default install path with msvc2017 64bit component | ||||
| 	# The Qt5_DIR should point to Qt5Config.cmake   -> C:/Qt/5.xx/msvc2017_64/lib/cmake/Qt5 | ||||
| 	# The CMAKE_PREFIX_PATH should point to the install directory -> C:/Qt/5.xx/msvc2017_64 | ||||
| 	FIRSTSUBDIR(SUBDIRQT "C:/Qt") | ||||
| 	SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${SUBDIRQT}/msvc2017_64") | ||||
| 	if (NOT DEFINED ENV{Qt5_DIR}) | ||||
| 		message(STATUS "Set Qt5_DIR to default install path C:/Qt") | ||||
| 		SET(Qt5_DIR "${SUBDIRQT}/msvc2017_64/lib/cmake/Qt5") | ||||
| 	endif() | ||||
| endif() | ||||
|  | ||||
| # Windows specific | ||||
| if(WIN32) | ||||
| 	# Path to .rc icon file for add_executable() calls | ||||
| 	SET ( WIN_RC_ICON_FILE ${CMAKE_SOURCE_DIR}/cmake/nsis/icon.rc) | ||||
| 	# Force gui app | ||||
| 	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") | ||||
| endif() | ||||
|  | ||||
| # Use GNU gold linker if available | ||||
| include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/LDGold.cmake) | ||||
| if (NOT WIN32) | ||||
| 	include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/LDGold.cmake) | ||||
| endif() | ||||
|  | ||||
| # Don't create new dynamic tags (RUNPATH) | ||||
| set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--disable-new-dtags") | ||||
| if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") | ||||
| 	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--disable-new-dtags") | ||||
| endif() | ||||
|  | ||||
| # setup -rpath to search for shared libs in BINARY/../lib folder | ||||
| if (UNIX AND NOT APPLE) | ||||
| @@ -318,7 +367,7 @@ if (ENABLE_V4L2) | ||||
| 		endif() | ||||
| 	endif (TURBOJPEG_FOUND) | ||||
|  | ||||
| 	 | ||||
|  | ||||
| 	if (TURBOJPEG_FOUND OR JPEG_FOUND) | ||||
| 		add_definitions(-DHAVE_JPEG_DECODER) | ||||
| 	endif() | ||||
|   | ||||
| @@ -3,10 +3,7 @@ You can participate in the translation. | ||||
| [](https://poeditor.com/join/project/Y4F6vHRFjA) | ||||
|  | ||||
| ## Development Setup | ||||
|  | ||||
| > TODO: Be more specific, provide a Visual Studio Code workspace with plugins and pre configured build tasks | ||||
|  | ||||
| Get Hyperion to compile: [Compile HowTo](CompileHowTo.md) | ||||
| You may already have an editor or IDE you want to use. In any case we provide a pre configured [Visual Studio Code](#visual-studio-code) setup. | ||||
|  | ||||
| ## Workflow | ||||
|  | ||||
| @@ -120,4 +117,16 @@ The amount of "%" mus match with following arguments | ||||
|  | ||||
| ## Commit specification | ||||
|  | ||||
| > TODO | ||||
| > TODO | ||||
|  | ||||
| ## Visual Studio Code | ||||
| **We assume that you sucessfully compiled Hyperion with the [Compile HowTo](CompileHowTo.md) WITHOUT Docker** \ | ||||
| If you want to use VSCode for development follow the steps. | ||||
|  | ||||
| - Install [VSCode](https://code.visualstudio.com/). On Ubuntu 16.04+ you can also use the [Snapcraft VSCode](https://snapcraft.io/code) package. | ||||
| - Linux: Install gdb `sudo apt-get install gdb` | ||||
| - Mac: ? | ||||
| - Open VSCode and click on _File_ -> _Open Workspace_ and select the file `hyperion.ng/.vscode/hyperion.code-workspace` | ||||
| - Install recommended extensions | ||||
| - If you installed the Task Explorer you can now use the defined vscode tasks to build Hyperion and configure cmake | ||||
| - For debugging you need to build Hyperion in Debug mode and start the correct Run config | ||||
|   | ||||
| @@ -74,6 +74,16 @@ brew install libusb | ||||
| brew install doxygen | ||||
| ``` | ||||
|  | ||||
| ## Windows (WIP) | ||||
| We assume a 64bit Windows 7 or higher. Install the following | ||||
| - [Git](https://git-scm.com/downloads) (Check: Add to PATH) | ||||
| - [Python 3 (Windows x86-64 executable installer)](https://www.python.org/downloads/windows/) (Check: Add to PATH and Debug Symbols) | ||||
| - [CMake (Windows win64-x64 Installer)](https://cmake.org/download/) (Check: Add to PATH) | ||||
| - [Qt5](https://www.qt.io/download-open-source) (Check: Component install: msvc 2017 64bit). No configuration for PATH is set, we assume the default install path. | ||||
| - [Visual Studio 2019 Build Tools](https://go.microsoft.com/fwlink/?linkid=840931) | ||||
|   - The Visual Studio 2019 Community Editor is not required but will be installed as part of the compiler and Windows SDK | ||||
|   - Select C++ Desktop Development Tools | ||||
|   - Now just select `MSVC v142 VS 2019 C++ x64/x86-Buildtools`, `C++-CMake Tools for Windows` and `Windows 10 SDK`. Everything else is not needed. | ||||
|  | ||||
| # Compiling and installing Hyperion | ||||
|  | ||||
| @@ -148,6 +158,13 @@ Platform should be auto detected and refer to osx, you can also force osx: | ||||
| cmake -DPLATFORM=osx -DCMAKE_BUILD_TYPE=Release .. | ||||
| ``` | ||||
|  | ||||
| To generate files on Windows (Release+Debug capable): | ||||
|  | ||||
| Platform should be auto detected and refer to windows, you can also force windows: | ||||
| ``` | ||||
| cmake -DPLATFORM=windows -G "Windows 16 2019" .. | ||||
| ``` | ||||
|  | ||||
| ### Run make to build Hyperion | ||||
| The `-j $(nproc)` specifies the amount of CPU cores to use. | ||||
| ```bash | ||||
| @@ -160,6 +177,11 @@ On a mac you can use ``sysctl -n hw.ncpu`` to get the number of available CPU co | ||||
| make -j $(sysctl -n hw.ncpu) | ||||
| ``` | ||||
|  | ||||
| On Windows run | ||||
| ```bash | ||||
| cmake --build . --config Release -- -maxcpucount | ||||
| ``` | ||||
|  | ||||
| ### Install hyperion into your system | ||||
|  | ||||
| Copy all necessary files to ``/usr/local/share/hyperion`` | ||||
|   | ||||
| @@ -30,6 +30,9 @@ | ||||
| // Define to enable the tinkerforge device | ||||
| #cmakedefine ENABLE_TINKERFORGE | ||||
|  | ||||
| // Define to enable avahi | ||||
| #cmakedefine ENABLE_AVAHI | ||||
|  | ||||
| // Define to enable the usb / hid devices | ||||
| #cmakedefine ENABLE_USB_HID | ||||
|  | ||||
|   | ||||
							
								
								
									
										21
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								README.md
									
									
									
									
									
								
							| @@ -23,22 +23,31 @@ | ||||
| * A scriptable (Python) effect engine | ||||
| * A multi language web interface to configure and remote control hyperion | ||||
|  | ||||
| If you need further support please open a topic at the forum!   | ||||
| If you need further support please open a topic at the forum! | ||||
| [](https://www.hyperion-project.org) | ||||
|  | ||||
| ## Contributing   | ||||
| ## Contributing | ||||
|  | ||||
| Contributions are welcome! Feel free to join us! We are looking always for people who wants to participate.   | ||||
| Contributions are welcome! Feel free to join us! We are looking always for people who wants to participate. | ||||
| [](https://github.com/hyperion-project/hyperion.ng/graphs/contributors) | ||||
|  | ||||
| For an example, you can participate in the translation.   | ||||
| For an example, you can participate in the translation. | ||||
| [](https://poeditor.com/join/project/Y4F6vHRFjA) | ||||
|  | ||||
| ## Requirements | ||||
| Debian 9, Ubuntu 16.04 or higher. Windows is not supported currently. | ||||
| Debian 9, Ubuntu 16.04 or higher. | ||||
|  | ||||
| We provide a macOS Build but we can not support this. | ||||
|  | ||||
| ## Documentation | ||||
| Covers these topics (WorkInProgress) | ||||
| - Installtion | ||||
| - Configuration | ||||
| - Effect development | ||||
| - JSON API | ||||
|  | ||||
| [Visit Documentation](https://docs.hyperion-project.org) | ||||
|  | ||||
| ## Building | ||||
| See [CompileHowto](CompileHowto.md) and [CrossCompileHowto](CrossCompileHowto.md). | ||||
|  | ||||
| @@ -46,6 +55,6 @@ See [CompileHowto](CompileHowto.md) and [CrossCompileHowto](CrossCompileHowto.md | ||||
| Alpha releases available from the [Hyperion release page](https://github.com/hyperion-project/hyperion.ng/releases) | ||||
|  | ||||
| ## License | ||||
| The source is released under MIT-License (see http://opensource.org/licenses/MIT).   | ||||
| The source is released under MIT-License (see http://opensource.org/licenses/MIT). | ||||
| [](https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/LICENSE) | ||||
|  | ||||
|   | ||||
| @@ -62,7 +62,7 @@ function debugMessage(msg) | ||||
| function updateSessions() | ||||
| { | ||||
| 	var sess = window.serverInfo.sessions; | ||||
| 	if (sess.length) | ||||
| 	if (sess && sess.length) | ||||
| 	{ | ||||
| 		window.wSess = []; | ||||
| 		for(var i = 0; i<sess.length; i++) | ||||
|   | ||||
							
								
								
									
										286
									
								
								cmake/Dependencies.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								cmake/Dependencies.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,286 @@ | ||||
| macro(DeployUnix TARGET) | ||||
| 	set(TARGET_FILE ${CMAKE_BINARY_DIR}/bin/${TARGET}) | ||||
| 	set(SYSTEM_LIBS_SKIP | ||||
| 		"libc" | ||||
| 		"libdl" | ||||
| 		"libexpat" | ||||
| 		"libfontconfig" | ||||
| 		"libfreetype" | ||||
| 		"libgcc_s" | ||||
| 		"libgcrypt" | ||||
| 		"libGL" | ||||
| 		"libGLdispatch" | ||||
| 		"libglib-2" | ||||
| 		"libGLX" | ||||
| 		"libgpg-error" | ||||
| 		"libm" | ||||
| 		"libpthread" | ||||
| 		"librt" | ||||
| 		"libstdc++" | ||||
| 		"libudev" | ||||
| 		"libusb-1" | ||||
| 		"libutil" | ||||
| 		"libX11" | ||||
| 		"libz" | ||||
| 	) | ||||
|  | ||||
| 	if(EXISTS ${TARGET_FILE}) | ||||
| 		include(GetPrerequisites) | ||||
|  | ||||
| 		if (APPLE) | ||||
| 			set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) | ||||
| 		endif(APPLE) | ||||
|  | ||||
| 		# Extract dependencies ignoring the system ones | ||||
| 		get_prerequisites(${TARGET_FILE} DEPENDENCIES 0 1 "" "") | ||||
|  | ||||
| 		# Append symlink and non-symlink dependencies to the list | ||||
| 		set(PREREQUISITE_LIBS "") | ||||
| 		foreach(DEPENDENCY ${DEPENDENCIES}) | ||||
| 			get_filename_component(resolved ${DEPENDENCY} NAME_WE) | ||||
| 			list(FIND SYSTEM_LIBS_SKIP ${resolved} _index) | ||||
| 			if (${_index} GREATER -1) | ||||
| 				continue() # Skip system libraries | ||||
| 			else() | ||||
| 				gp_resolve_item("${TARGET_FILE}" "${DEPENDENCY}" "" "" resolved_file) | ||||
| 				get_filename_component(resolved_file ${resolved_file} ABSOLUTE) | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${resolved_file}) | ||||
| 				get_filename_component(file_canonical ${resolved_file} REALPATH) | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 			endif() | ||||
| 		endforeach() | ||||
|  | ||||
| 		# Append the OpenSSL library to the list | ||||
| 		find_package(OpenSSL 1.0.0 REQUIRED) | ||||
| 		if (OPENSSL_FOUND) | ||||
| 			foreach(openssl_lib ${OPENSSL_LIBRARIES}) | ||||
| 				get_prerequisites(${openssl_lib} openssl_deps 0 1 "" "") | ||||
|  | ||||
| 				foreach(openssl_dep ${openssl_deps}) | ||||
| 					get_filename_component(resolved ${openssl_dep} NAME_WE) | ||||
| 					list(FIND SYSTEM_LIBS_SKIP ${resolved} _index) | ||||
| 					if (${_index} GREATER -1) | ||||
| 						continue() # Skip system libraries | ||||
| 					else() | ||||
| 						gp_resolve_item("${openssl_lib}" "${openssl_dep}" "" "" resolved_file) | ||||
| 						get_filename_component(resolved_file ${resolved_file} ABSOLUTE) | ||||
| 						gp_append_unique(PREREQUISITE_LIBS ${resolved_file}) | ||||
| 						get_filename_component(file_canonical ${resolved_file} REALPATH) | ||||
| 						gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 					endif() | ||||
| 				endforeach() | ||||
|  | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${openssl_lib}) | ||||
| 				get_filename_component(file_canonical ${openssl_lib} REALPATH) | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 			endforeach() | ||||
| 		endif(OPENSSL_FOUND) | ||||
|  | ||||
| 		# Detect the Qt5 plugin directory, source: https://github.com/lxde/lxqt-qtplugin/blob/master/src/CMakeLists.txt | ||||
| 		get_target_property(QT_QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE} IMPORTED_LOCATION) | ||||
| 		execute_process( | ||||
| 			COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS | ||||
| 			OUTPUT_VARIABLE QT_PLUGINS_DIR | ||||
| 			OUTPUT_STRIP_TRAILING_WHITESPACE | ||||
| 		) | ||||
|  | ||||
| 		# Copy Qt plugins to 'share/hyperion/lib' | ||||
| 		if(QT_PLUGINS_DIR) | ||||
| 			foreach(PLUGIN "platforms" "sqldrivers" "imageformats") | ||||
| 				if(EXISTS ${QT_PLUGINS_DIR}/${PLUGIN}) | ||||
| 					file(GLOB files "${QT_PLUGINS_DIR}/${PLUGIN}/*") | ||||
| 					foreach(file ${files}) | ||||
| 						get_prerequisites(${file} PLUGINS 0 1 "" "") | ||||
|  | ||||
| 						foreach(DEPENDENCY ${PLUGINS}) | ||||
| 							get_filename_component(resolved ${DEPENDENCY} NAME_WE) | ||||
| 							list(FIND SYSTEM_LIBS_SKIP ${resolved} _index) | ||||
| 							if (${_index} GREATER -1) | ||||
| 								continue() # Skip system libraries | ||||
| 							else() | ||||
| 								gp_resolve_item("${file}" "${DEPENDENCY}" "" "" resolved_file) | ||||
| 								get_filename_component(resolved_file ${resolved_file} ABSOLUTE) | ||||
| 								gp_append_unique(PREREQUISITE_LIBS ${resolved_file}) | ||||
| 								get_filename_component(file_canonical ${resolved_file} REALPATH) | ||||
| 								gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 							endif() | ||||
| 						endforeach() | ||||
|  | ||||
| 						install( | ||||
| 							FILES ${file} | ||||
| 							DESTINATION "share/hyperion/lib/${PLUGIN}" | ||||
| 							COMPONENT "Hyperion" | ||||
| 						) | ||||
| 					endforeach() | ||||
| 				endif() | ||||
| 			endforeach() | ||||
| 		endif(QT_PLUGINS_DIR) | ||||
|  | ||||
| 		# Create a qt.conf file in 'share/hyperion/bin' to override hard-coded search paths in Qt plugins | ||||
| 		file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=../lib/\n") | ||||
| 		install( | ||||
| 			FILES "${CMAKE_BINARY_DIR}/qt.conf" | ||||
| 			DESTINATION "share/hyperion/bin" | ||||
| 			COMPONENT "Hyperion" | ||||
| 		) | ||||
|  | ||||
| 		# Copy dependencies to 'share/hyperion/lib' | ||||
| 		foreach(PREREQUISITE_LIB ${PREREQUISITE_LIBS}) | ||||
| 			install( | ||||
| 				FILES ${PREREQUISITE_LIB} | ||||
| 				DESTINATION "share/hyperion/lib" | ||||
| 				COMPONENT "Hyperion" | ||||
| 			) | ||||
| 		endforeach() | ||||
|  | ||||
| 		if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
|  | ||||
| 			# Detect the Python modules directory | ||||
| 			execute_process( | ||||
| 				COMMAND ${Python3_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(standard_lib=True))" | ||||
| 				OUTPUT_VARIABLE PYTHON_MODULES_DIR | ||||
| 				OUTPUT_STRIP_TRAILING_WHITESPACE | ||||
| 			) | ||||
| 		else() | ||||
|  | ||||
| 			# Detect the Python modules directory | ||||
| 			execute_process( | ||||
| 				COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(standard_lib=True))" | ||||
| 				OUTPUT_VARIABLE PYTHON_MODULES_DIR | ||||
| 				OUTPUT_STRIP_TRAILING_WHITESPACE | ||||
| 			) | ||||
|  | ||||
| 		endif() | ||||
|  | ||||
| 		# Copy Python modules to 'share/hyperion/lib/python' | ||||
| 		if (PYTHON_MODULES_DIR) | ||||
| 			install( | ||||
| 				DIRECTORY ${PYTHON_MODULES_DIR}/ | ||||
| 				DESTINATION "share/hyperion/lib/python" | ||||
| 				COMPONENT "Hyperion" | ||||
| 			) | ||||
| 		endif(PYTHON_MODULES_DIR) | ||||
| 	else() | ||||
| 		# Run CMake after target was built to run get_prerequisites on ${TARGET_FILE} | ||||
| 		add_custom_command( | ||||
| 			TARGET ${TARGET} POST_BUILD | ||||
| 			COMMAND ${CMAKE_COMMAND} | ||||
| 			ARGS ${CMAKE_SOURCE_DIR} | ||||
| 			WORKING_DIRECTORY ${CMAKE_BINARY_DIR} | ||||
| 			VERBATIM | ||||
| 		) | ||||
| 	endif() | ||||
| endmacro() | ||||
|  | ||||
| macro(DeployWindows TARGET) | ||||
| 	# TODO Find out what build type it is | ||||
| 	set(TARGET_FILE ${CMAKE_BINARY_DIR}/bin/Release/${TARGET}.exe) | ||||
|  | ||||
| 	if(EXISTS ${TARGET_FILE}) | ||||
| 		find_package(Qt5Core REQUIRED) | ||||
|  | ||||
| 		# Find the windeployqt binaries | ||||
| 		get_target_property(QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) | ||||
| 		get_filename_component(QT_BIN_DIR "${QMAKE_EXECUTABLE}" DIRECTORY) | ||||
| 		find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_BIN_DIR}") | ||||
|  | ||||
| 		# Collect the runtime libraries | ||||
| 		get_filename_component(COMPILER_PATH "${CMAKE_CXX_COMPILER}" DIRECTORY) | ||||
| 		set(WINDEPLOYQT_PARAMS --no-angle --no-opengl-sw) | ||||
|  | ||||
| 		execute_process( | ||||
| 			COMMAND "${CMAKE_COMMAND}" -E | ||||
| 			env "PATH=${COMPILER_PATH};${QT_BIN_DIR}" "${WINDEPLOYQT_EXECUTABLE}" | ||||
|             --dry-run | ||||
|             ${WINDEPLOYQT_PARAMS} | ||||
|             --list mapping | ||||
|             "${TARGET_FILE}" | ||||
|             OUTPUT_VARIABLE DEPS | ||||
| 			OUTPUT_STRIP_TRAILING_WHITESPACE | ||||
| 		) | ||||
|  | ||||
| 		# Parse DEPS into a semicolon-separated list. | ||||
| 		separate_arguments(DEPENDENCIES WINDOWS_COMMAND ${DEPS}) | ||||
| 		string(REPLACE "\\" "/" DEPENDENCIES "${DEPENDENCIES}") | ||||
|  | ||||
| 		# Copy dependencies to 'hyperion/lib' or 'hyperion' | ||||
| 		while (DEPENDENCIES) | ||||
| 			list(GET DEPENDENCIES 0 src) | ||||
| 			list(GET DEPENDENCIES 1 dst) | ||||
| 			get_filename_component(dst ${dst} DIRECTORY) | ||||
|  | ||||
| 			if (NOT "${dst}" STREQUAL "") | ||||
| 				install( | ||||
| 					FILES ${src} | ||||
| 					DESTINATION "lib/${dst}" | ||||
| 					COMPONENT "Hyperion" | ||||
| 				) | ||||
| 			else() | ||||
| 				install( | ||||
| 					FILES ${src} | ||||
| 					DESTINATION "bin" | ||||
| 					COMPONENT "Hyperion" | ||||
| 				) | ||||
| 			endif() | ||||
|  | ||||
| 			list(REMOVE_AT DEPENDENCIES 0 1) | ||||
| 		endwhile() | ||||
|  | ||||
| 		# Create a qt.conf file in 'bin' to override hard-coded search paths in Qt plugins | ||||
| 		file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=../lib/\n") | ||||
| 		install( | ||||
| 			FILES "${CMAKE_BINARY_DIR}/qt.conf" | ||||
| 			DESTINATION "bin" | ||||
| 			COMPONENT "Hyperion" | ||||
| 		) | ||||
|  | ||||
| 		# Download embed python package | ||||
| 		# Currently only cmake version >= 3.12 implemented | ||||
| 		set(url "https://www.python.org/ftp/python/${Python3_VERSION}/") | ||||
| 		set(filename "python-${Python3_VERSION}-embed-amd64.zip") | ||||
|  | ||||
| 		if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${filename}" OR NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/python") | ||||
| 			file(DOWNLOAD "${url}${filename}" "${CMAKE_CURRENT_BINARY_DIR}/${filename}" | ||||
| 				STATUS result | ||||
| 			) | ||||
|  | ||||
| 			# Check if the download is successful | ||||
| 			list(GET result 0 result_code) | ||||
| 			if(NOT result_code EQUAL 0) | ||||
| 				list(GET result 1 reason) | ||||
| 				message(FATAL_ERROR "Could not download file ${url}${filename}: ${reason}") | ||||
| 			endif() | ||||
|  | ||||
| 			# Unpack downloaded embed python | ||||
| 			file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/python) | ||||
| 			file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python) | ||||
| 			execute_process( | ||||
| 				COMMAND ${CMAKE_COMMAND} -E tar -xfz "${CMAKE_CURRENT_BINARY_DIR}/${filename}" | ||||
| 				WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python | ||||
| 				OUTPUT_QUIET | ||||
| 			) | ||||
| 		endif() | ||||
|  | ||||
| 		# Copy pythonXX.dll and pythonXX.zip to 'hyperion' | ||||
| 		foreach(PYTHON_FILE | ||||
| 			"python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}.dll" | ||||
| 			"python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}.zip" | ||||
| 		) | ||||
| 			install( | ||||
| 				FILES ${CMAKE_CURRENT_BINARY_DIR}/python/${PYTHON_FILE} | ||||
| 				DESTINATION "bin" | ||||
| 				COMPONENT "Hyperion" | ||||
| 			) | ||||
| 		endforeach() | ||||
|  | ||||
| 	else() | ||||
| 		# Run CMake after target was built | ||||
| 		add_custom_command( | ||||
| 			TARGET ${TARGET} POST_BUILD | ||||
| 			COMMAND ${CMAKE_COMMAND} | ||||
| 			ARGS ${CMAKE_SOURCE_DIR} | ||||
| 			WORKING_DIRECTORY ${CMAKE_BINARY_DIR} | ||||
| 			VERBATIM | ||||
| 		) | ||||
| 	endif() | ||||
| endmacro() | ||||
							
								
								
									
										635
									
								
								cmake/FindWindowsSDK.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										635
									
								
								cmake/FindWindowsSDK.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,635 @@ | ||||
| # - Find the Windows SDK aka Platform SDK | ||||
| # | ||||
| # Relevant Wikipedia article: http://en.wikipedia.org/wiki/Microsoft_Windows_SDK | ||||
| # | ||||
| # Pass "COMPONENTS tools" to ignore Visual Studio version checks: in case | ||||
| # you just want the tool binaries to run, rather than the libraries and headers | ||||
| # for compiling. | ||||
| # | ||||
| # Variables: | ||||
| #  WINDOWSSDK_FOUND - if any version of the windows or platform SDK was found that is usable with the current version of visual studio | ||||
| #  WINDOWSSDK_LATEST_DIR | ||||
| #  WINDOWSSDK_LATEST_NAME | ||||
| #  WINDOWSSDK_FOUND_PREFERENCE - if we found an entry indicating a "preferred" SDK listed for this visual studio version | ||||
| #  WINDOWSSDK_PREFERRED_DIR | ||||
| #  WINDOWSSDK_PREFERRED_NAME | ||||
| # | ||||
| #  WINDOWSSDK_DIRS - contains no duplicates, ordered most recent first. | ||||
| #  WINDOWSSDK_PREFERRED_FIRST_DIRS - contains no duplicates, ordered with preferred first, followed by the rest in descending recency | ||||
| # | ||||
| # Functions: | ||||
| #  windowssdk_name_lookup(<directory> <output variable>) - Find the name corresponding with the SDK directory you pass in, or | ||||
| #     NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. | ||||
| # | ||||
| #  windowssdk_build_lookup(<directory> <output variable>) - Find the build version number corresponding with the SDK directory you pass in, or | ||||
| #     NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. | ||||
| # | ||||
| #  get_windowssdk_from_component(<file or dir> <output variable>) - Given a library or include dir, | ||||
| #     find the Windows SDK root dir corresponding to it, or NOTFOUND if unrecognized. | ||||
| # | ||||
| #  get_windowssdk_library_dirs(<directory> <output variable>) - Find the architecture-appropriate | ||||
| #     library directories corresponding to the SDK directory you pass in (or NOTFOUND if none) | ||||
| # | ||||
| #  get_windowssdk_library_dirs_multiple(<output variable> <directory> ...) - Find the architecture-appropriate | ||||
| #     library directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. | ||||
| #     Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. | ||||
| # | ||||
| #  get_windowssdk_include_dirs(<directory> <output variable>) - Find the | ||||
| #     include directories corresponding to the SDK directory you pass in (or NOTFOUND if none) | ||||
| # | ||||
| #  get_windowssdk_include_dirs_multiple(<output variable> <directory> ...) - Find the | ||||
| #     include directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. | ||||
| #     Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. | ||||
| # | ||||
| # Requires these CMake modules: | ||||
| #  FindPackageHandleStandardArgs (known included with CMake >=2.6.2) | ||||
| # | ||||
| # Original Author: | ||||
| # 2012 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> | ||||
| # http://academic.cleardefinition.com | ||||
| # Iowa State University HCI Graduate Program/VRAC | ||||
| # | ||||
| # Copyright Iowa State University 2012. | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at | ||||
| # http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| set(_preferred_sdk_dirs) # pre-output | ||||
| set(_win_sdk_dirs) # pre-output | ||||
| set(_win_sdk_versanddirs) # pre-output | ||||
| set(_win_sdk_buildsanddirs) # pre-output | ||||
| set(_winsdk_vistaonly) # search parameters | ||||
| set(_winsdk_kits) # search parameters | ||||
|  | ||||
|  | ||||
| set(_WINDOWSSDK_ANNOUNCE OFF) | ||||
| if(NOT WINDOWSSDK_FOUND AND (NOT WindowsSDK_FIND_QUIETLY)) | ||||
| 	set(_WINDOWSSDK_ANNOUNCE ON) | ||||
| endif() | ||||
| macro(_winsdk_announce) | ||||
| 	if(_WINSDK_ANNOUNCE) | ||||
| 		message(STATUS ${ARGN}) | ||||
| 	endif() | ||||
| endmacro() | ||||
|  | ||||
| # See https://developer.microsoft.com/en-us/windows/downloads/sdk-archive - | ||||
| # although version numbers listed on that page don't necessarily match the directory | ||||
| # used by the installer. | ||||
| set(_winsdk_win10vers | ||||
| 	10.0.18362.0 # Win10 1903 "19H1" | ||||
| 	10.0.17763.0 # Win10 1809 "October 2018 Update" | ||||
| 	10.0.17134.0 # Redstone 4 aka Win10 1803 "April 2018 Update" | ||||
| 	10.0.17133.0 # Redstone 4 aka Win10 1803 "April 2018 Update" | ||||
| 	10.0.16299.0 # Redstone 3 aka Win10 1709 "Fall Creators Update" | ||||
| 	10.0.15063.0 # Redstone 2 aka Win10 1703 "Creators Update" | ||||
| 	10.0.14393.0 # Redstone aka Win10 1607 "Anniversary Update" | ||||
| 	10.0.10586.0 # TH2 aka Win10 1511 | ||||
| 	10.0.10240.0 # Win10 RTM | ||||
| 	10.0.10150.0 # just ucrt | ||||
| 	10.0.10056.0 | ||||
| ) | ||||
|  | ||||
| if(WindowsSDK_FIND_COMPONENTS MATCHES "tools") | ||||
| 	set(_WINDOWSSDK_IGNOREMSVC ON) | ||||
| 	_winsdk_announce("Checking for tools from Windows/Platform SDKs...") | ||||
| else() | ||||
| 	set(_WINDOWSSDK_IGNOREMSVC OFF) | ||||
| 	_winsdk_announce("Checking for Windows/Platform SDKs...") | ||||
| endif() | ||||
|  | ||||
| # Appends to the three main pre-output lists used only if the path exists | ||||
| # and is not already in the list. | ||||
| function(_winsdk_conditional_append _vername _build _path) | ||||
| 	if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}")) | ||||
| 		# Path invalid - do not add | ||||
| 		return() | ||||
| 	endif() | ||||
| 	list(FIND _win_sdk_dirs "${_path}" _win_sdk_idx) | ||||
| 	if(_win_sdk_idx GREATER -1) | ||||
| 		# Path already in list - do not add | ||||
| 		return() | ||||
| 	endif() | ||||
| 	_winsdk_announce( " - ${_vername}, Build ${_build} @ ${_path}") | ||||
| 	# Not yet in the list, so we'll add it | ||||
| 	list(APPEND _win_sdk_dirs "${_path}") | ||||
| 	set(_win_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE) | ||||
| 	list(APPEND | ||||
| 		_win_sdk_versanddirs | ||||
| 		"${_vername}" | ||||
| 		"${_path}") | ||||
| 	set(_win_sdk_versanddirs "${_win_sdk_versanddirs}" CACHE INTERNAL "" FORCE) | ||||
| 	list(APPEND | ||||
| 		_win_sdk_buildsanddirs | ||||
| 		"${_build}" | ||||
| 		"${_path}") | ||||
| 	set(_win_sdk_buildsanddirs "${_win_sdk_buildsanddirs}" CACHE INTERNAL "" FORCE) | ||||
| endfunction() | ||||
|  | ||||
| # Appends to the "preferred SDK" lists only if the path exists | ||||
| function(_winsdk_conditional_append_preferred _info _path) | ||||
| 	if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}")) | ||||
| 		# Path invalid - do not add | ||||
| 		return() | ||||
| 	endif() | ||||
|  | ||||
| 	get_filename_component(_path "${_path}" ABSOLUTE) | ||||
|  | ||||
| 	list(FIND _win_sdk_preferred_sdk_dirs "${_path}" _win_sdk_idx) | ||||
| 	if(_win_sdk_idx GREATER -1) | ||||
| 		# Path already in list - do not add | ||||
| 		return() | ||||
| 	endif() | ||||
| 	_winsdk_announce( " - Found \"preferred\" SDK ${_info} @ ${_path}") | ||||
| 	# Not yet in the list, so we'll add it | ||||
| 	list(APPEND _win_sdk_preferred_sdk_dirs "${_path}") | ||||
| 	set(_win_sdk_preferred_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE) | ||||
|  | ||||
| 	# Just in case we somehow missed it: | ||||
| 	_winsdk_conditional_append("${_info}" "" "${_path}") | ||||
| endfunction() | ||||
|  | ||||
| # Given a version like v7.0A, looks for an SDK in the registry under "Microsoft SDKs". | ||||
| # If the given version might be in both HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows | ||||
| # and HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots aka "Windows Kits", | ||||
| # use this macro first, since these registry keys usually have more information. | ||||
| # | ||||
| # Pass a "default" build number as an extra argument in case we can't find it. | ||||
| function(_winsdk_check_microsoft_sdks_registry _winsdkver) | ||||
| 	set(SDKKEY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\${_winsdkver}") | ||||
| 	get_filename_component(_sdkdir | ||||
| 		"[${SDKKEY};InstallationFolder]" | ||||
| 		ABSOLUTE) | ||||
|  | ||||
| 	set(_sdkname "Windows SDK ${_winsdkver}") | ||||
|  | ||||
| 	# Default build number passed as extra argument | ||||
| 	set(_build ${ARGN}) | ||||
| 	# See if the registry holds a Microsoft-mutilated, err, designated, product name | ||||
| 	# (just using get_filename_component to execute the registry lookup) | ||||
| 	get_filename_component(_sdkproductname | ||||
| 		"[${SDKKEY};ProductName]" | ||||
| 		NAME) | ||||
| 	if(NOT "${_sdkproductname}" MATCHES "registry") | ||||
| 		# Got a product name | ||||
| 		set(_sdkname "${_sdkname} (${_sdkproductname})") | ||||
| 	endif() | ||||
|  | ||||
| 	# try for a version to augment our name | ||||
| 	# (just using get_filename_component to execute the registry lookup) | ||||
| 	get_filename_component(_sdkver | ||||
| 		"[${SDKKEY};ProductVersion]" | ||||
| 		NAME) | ||||
| 	if(NOT "${_sdkver}" MATCHES "registry" AND NOT MATCHES) | ||||
| 		# Got a version | ||||
| 		if(NOT "${_sdkver}" MATCHES "\\.\\.") | ||||
| 			# and it's not an invalid one with two dots in it: | ||||
| 			# use to override the default build | ||||
| 			set(_build ${_sdkver}) | ||||
| 			if(NOT "${_sdkname}" MATCHES "${_sdkver}") | ||||
| 				# Got a version that's not already in the name, let's use it to improve our name. | ||||
| 				set(_sdkname "${_sdkname} (${_sdkver})") | ||||
| 			endif() | ||||
| 		endif() | ||||
| 	endif() | ||||
| 	_winsdk_conditional_append("${_sdkname}" "${_build}" "${_sdkdir}") | ||||
| endfunction() | ||||
|  | ||||
| # Given a name for identification purposes, the build number, and a key (technically a "value name") | ||||
| # corresponding to a Windows SDK packaged as a "Windows Kit", look for it | ||||
| # in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots | ||||
| # Note that the key or "value name" tends to be something weird like KitsRoot81 - | ||||
| # no easy way to predict, just have to observe them in the wild. | ||||
| # Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these: | ||||
| # sometimes you get keys in both parts of the registry (in the wow64 portion especially), | ||||
| # and the non-"Windows Kits" location is often more descriptive. | ||||
| function(_winsdk_check_windows_kits_registry _winkit_name _winkit_build _winkit_key) | ||||
| 	get_filename_component(_sdkdir | ||||
| 		"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;${_winkit_key}]" | ||||
| 		ABSOLUTE) | ||||
| 	_winsdk_conditional_append("${_winkit_name}" "${_winkit_build}" "${_sdkdir}") | ||||
| endfunction() | ||||
|  | ||||
| # Given a name for identification purposes and the build number | ||||
| # corresponding to a Windows 10 SDK packaged as a "Windows Kit", look for it | ||||
| # in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots | ||||
| # Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these: | ||||
| # sometimes you get keys in both parts of the registry (in the wow64 portion especially), | ||||
| # and the non-"Windows Kits" location is often more descriptive. | ||||
| function(_winsdk_check_win10_kits _winkit_build) | ||||
| 	get_filename_component(_sdkdir | ||||
| 		"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" | ||||
| 		ABSOLUTE) | ||||
| 	if(("${_sdkdir}" MATCHES "registry") OR (NOT EXISTS "${_sdkdir}")) | ||||
| 		return() # not found | ||||
| 	endif() | ||||
| 	if(EXISTS "${_sdkdir}/Include/${_winkit_build}/um") | ||||
| 		_winsdk_conditional_append("Windows Kits 10 (Build ${_winkit_build})" "${_winkit_build}" "${_sdkdir}") | ||||
| 	endif() | ||||
| endfunction() | ||||
|  | ||||
| # Given a name for indentification purposes, the build number, and the associated package GUID, | ||||
| # look in the registry under both HKLM and HKCU in \\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\ | ||||
| # for that guid and the SDK it points to. | ||||
| function(_winsdk_check_platformsdk_registry _platformsdkname _build _platformsdkguid) | ||||
| 	foreach(_winsdk_hive HKEY_LOCAL_MACHINE HKEY_CURRENT_USER) | ||||
| 		get_filename_component(_sdkdir | ||||
| 			"[${_winsdk_hive}\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\${_platformsdkguid};Install Dir]" | ||||
| 			ABSOLUTE) | ||||
| 		_winsdk_conditional_append("${_platformsdkname} (${_build})" "${_build}" "${_sdkdir}") | ||||
| 	endforeach() | ||||
| endfunction() | ||||
|  | ||||
| ### | ||||
| # Detect toolchain information: to know whether it's OK to use Vista+ only SDKs | ||||
| ### | ||||
| set(_winsdk_vistaonly_ok OFF) | ||||
| if(MSVC AND NOT _WINDOWSSDK_IGNOREMSVC) | ||||
| 	# VC 10 and older has broad target support | ||||
| 	if(MSVC_VERSION LESS 1700) | ||||
| 		# VC 11 by default targets Vista and later only, so we can add a few more SDKs that (might?) only work on vista+ | ||||
| 	elseif("${CMAKE_VS_PLATFORM_TOOLSET}" MATCHES "_xp") | ||||
| 		# This is the XP-compatible v110+ toolset | ||||
| 	elseif("${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v100" OR "${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v90") | ||||
| 		# This is the VS2010/VS2008 toolset | ||||
| 	else() | ||||
| 		# OK, we're VC11 or newer and not using a backlevel or XP-compatible toolset. | ||||
| 		# These versions have no XP (and possibly Vista pre-SP1) support | ||||
| 		set(_winsdk_vistaonly_ok ON) | ||||
| 		if(_WINDOWSSDK_ANNOUNCE AND NOT _WINDOWSSDK_VISTAONLY_PESTERED) | ||||
| 			set(_WINDOWSSDK_VISTAONLY_PESTERED ON CACHE INTERNAL "" FORCE) | ||||
| 			message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!") | ||||
| 		endif() | ||||
| 	endif() | ||||
| endif() | ||||
| if(_WINDOWSSDK_IGNOREMSVC) | ||||
| 	set(_winsdk_vistaonly_ok ON) | ||||
| endif() | ||||
|  | ||||
| ### | ||||
| # MSVC version checks - keeps messy conditionals in one place | ||||
| # (messy because of _WINDOWSSDK_IGNOREMSVC) | ||||
| ### | ||||
| set(_winsdk_msvc_greater_1200 OFF) | ||||
| if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1200))) | ||||
| 	set(_winsdk_msvc_greater_1200 ON) | ||||
| endif() | ||||
| # Newer than VS .NET/VS Toolkit 2003 | ||||
| set(_winsdk_msvc_greater_1310 OFF) | ||||
| if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1310))) | ||||
| 	set(_winsdk_msvc_greater_1310 ON) | ||||
| endif() | ||||
|  | ||||
| # VS2005/2008 | ||||
| set(_winsdk_msvc_less_1600 OFF) | ||||
| if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION LESS 1600))) | ||||
| 	set(_winsdk_msvc_less_1600 ON) | ||||
| endif() | ||||
|  | ||||
| # VS2013+ | ||||
| set(_winsdk_msvc_not_less_1800 OFF) | ||||
| if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (NOT MSVC_VERSION LESS 1800))) | ||||
| 	set(_winsdk_msvc_not_less_1800 ON) | ||||
| endif() | ||||
|  | ||||
| ### | ||||
| # START body of find module | ||||
| ### | ||||
| if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003 | ||||
| 	### | ||||
| 	# Look for "preferred" SDKs | ||||
| 	### | ||||
|  | ||||
| 	# Environment variable for SDK dir | ||||
| 	if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) | ||||
| 		_winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}") | ||||
| 	endif() | ||||
|  | ||||
| 	if(_winsdk_msvc_less_1600) | ||||
| 		# Per-user current Windows SDK for VS2005/2008 | ||||
| 		get_filename_component(_sdkdir | ||||
| 			"[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" | ||||
| 			ABSOLUTE) | ||||
| 		_winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}") | ||||
|  | ||||
| 		# System-wide current Windows SDK for VS2005/2008 | ||||
| 		get_filename_component(_sdkdir | ||||
| 			"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" | ||||
| 			ABSOLUTE) | ||||
| 		_winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}") | ||||
| 	endif() | ||||
|  | ||||
| 	### | ||||
| 	# Begin the massive list of SDK searching! | ||||
| 	### | ||||
| 	if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800) | ||||
| 		# These require at least Visual Studio 2013 (VC12) | ||||
|  | ||||
| 		_winsdk_check_microsoft_sdks_registry(v10.0A) | ||||
|  | ||||
| 		# Windows Software Development Kit (SDK) for Windows 10 | ||||
| 		# Several different versions living in the same directory - if nothing else we can assume RTM (10240) | ||||
| 		_winsdk_check_microsoft_sdks_registry(v10.0 10.0.10240.0) | ||||
| 		foreach(_win10build ${_winsdk_win10vers}) | ||||
| 			_winsdk_check_win10_kits(${_win10build}) | ||||
| 		endforeach() | ||||
| 	endif() # vista-only and 2013+ | ||||
|  | ||||
| 	# Included in Visual Studio 2013 | ||||
| 	# Includes the v120_xp toolset | ||||
| 	_winsdk_check_microsoft_sdks_registry(v8.1A 8.1.51636) | ||||
|  | ||||
| 	if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800) | ||||
| 		# Windows Software Development Kit (SDK) for Windows 8.1 | ||||
| 		# http://msdn.microsoft.com/en-gb/windows/desktop/bg162891 | ||||
| 		_winsdk_check_microsoft_sdks_registry(v8.1 8.1.25984.0) | ||||
| 		_winsdk_check_windows_kits_registry("Windows Kits 8.1" 8.1.25984.0 KitsRoot81) | ||||
| 	endif() # vista-only and 2013+ | ||||
|  | ||||
| 	if(_winsdk_vistaonly_ok) | ||||
| 		# Included in Visual Studio 2012 | ||||
| 		_winsdk_check_microsoft_sdks_registry(v8.0A 8.0.50727) | ||||
|  | ||||
| 		# Microsoft Windows SDK for Windows 8 and .NET Framework 4.5 | ||||
| 		# This is the first version to also include the DirectX SDK | ||||
| 		# http://msdn.microsoft.com/en-US/windows/desktop/hh852363.aspx | ||||
| 		_winsdk_check_microsoft_sdks_registry(v8.0 6.2.9200.16384) | ||||
| 		_winsdk_check_windows_kits_registry("Windows Kits 8.0" 6.2.9200.16384 KitsRoot) | ||||
| 	endif() # vista-only | ||||
|  | ||||
| 	# Included with VS 2012 Update 1 or later | ||||
| 	# Introduces v110_xp toolset | ||||
| 	_winsdk_check_microsoft_sdks_registry(v7.1A 7.1.51106) | ||||
| 	if(_winsdk_vistaonly_ok) | ||||
| 		# Microsoft Windows SDK for Windows 7 and .NET Framework 4 | ||||
| 		# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b | ||||
| 		_winsdk_check_microsoft_sdks_registry(v7.1 7.1.7600.0.30514) | ||||
| 	endif() # vista-only | ||||
|  | ||||
| 	# Included with VS 2010 | ||||
| 	_winsdk_check_microsoft_sdks_registry(v7.0A 6.1.7600.16385) | ||||
|  | ||||
| 	# Windows SDK for Windows 7 and .NET Framework 3.5 SP1 | ||||
| 	# Works with VC9 | ||||
| 	# http://www.microsoft.com/en-us/download/details.aspx?id=18950 | ||||
| 	_winsdk_check_microsoft_sdks_registry(v7.0 6.1.7600.16385) | ||||
|  | ||||
| 	# Two versions call themselves "v6.1": | ||||
| 	# Older: | ||||
| 	# Windows Vista Update & .NET 3.0 SDK | ||||
| 	# http://www.microsoft.com/en-us/download/details.aspx?id=14477 | ||||
|  | ||||
| 	# Newer: | ||||
| 	# Windows Server 2008 & .NET 3.5 SDK | ||||
| 	# may have broken VS9SP1? they recommend v7.0 instead, or a KB... | ||||
| 	# http://www.microsoft.com/en-us/download/details.aspx?id=24826 | ||||
| 	_winsdk_check_microsoft_sdks_registry(v6.1 6.1.6000.16384.10) | ||||
|  | ||||
| 	# Included in VS 2008 | ||||
| 	_winsdk_check_microsoft_sdks_registry(v6.0A 6.1.6723.1) | ||||
|  | ||||
| 	# Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components | ||||
| 	# http://blogs.msdn.com/b/stanley/archive/2006/11/08/microsoft-windows-software-development-kit-for-windows-vista-and-net-framework-3-0-runtime-components.aspx | ||||
| 	_winsdk_check_microsoft_sdks_registry(v6.0 6.0.6000.16384) | ||||
| endif() | ||||
|  | ||||
| # Let's not forget the Platform SDKs, which sometimes are useful! | ||||
| if(_winsdk_msvc_greater_1200) | ||||
| 	_winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 R2" "5.2.3790.2075.51" "D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1") | ||||
| 	_winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 SP1" "5.2.3790.1830.15" "8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3") | ||||
| endif() | ||||
| ### | ||||
| # Finally, look for "preferred" SDKs | ||||
| ### | ||||
| if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003 | ||||
|  | ||||
|  | ||||
| 	# Environment variable for SDK dir | ||||
| 	if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) | ||||
| 		_winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}") | ||||
| 	endif() | ||||
|  | ||||
| 	if(_winsdk_msvc_less_1600) | ||||
| 		# Per-user current Windows SDK for VS2005/2008 | ||||
| 		get_filename_component(_sdkdir | ||||
| 			"[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" | ||||
| 			ABSOLUTE) | ||||
| 		_winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}") | ||||
|  | ||||
| 		# System-wide current Windows SDK for VS2005/2008 | ||||
| 		get_filename_component(_sdkdir | ||||
| 			"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" | ||||
| 			ABSOLUTE) | ||||
| 		_winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}") | ||||
| 	endif() | ||||
| endif() | ||||
|  | ||||
|  | ||||
| function(windowssdk_name_lookup _dir _outvar) | ||||
| 	list(FIND _win_sdk_versanddirs "${_dir}" _diridx) | ||||
| 	math(EXPR _idx "${_diridx} - 1") | ||||
| 	if(${_idx} GREATER -1) | ||||
| 		list(GET _win_sdk_versanddirs ${_idx} _ret) | ||||
| 	else() | ||||
| 		set(_ret "NOTFOUND") | ||||
| 	endif() | ||||
| 	set(${_outvar} "${_ret}" PARENT_SCOPE) | ||||
| endfunction() | ||||
|  | ||||
| function(windowssdk_build_lookup _dir _outvar) | ||||
| 	list(FIND _win_sdk_buildsanddirs "${_dir}" _diridx) | ||||
| 	math(EXPR _idx "${_diridx} - 1") | ||||
| 	if(${_idx} GREATER -1) | ||||
| 		list(GET _win_sdk_buildsanddirs ${_idx} _ret) | ||||
| 	else() | ||||
| 		set(_ret "NOTFOUND") | ||||
| 	endif() | ||||
| 	set(${_outvar} "${_ret}" PARENT_SCOPE) | ||||
| endfunction() | ||||
|  | ||||
| # If we found something... | ||||
| if(_win_sdk_dirs) | ||||
| 	list(GET _win_sdk_dirs 0 WINDOWSSDK_LATEST_DIR) | ||||
| 	windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}" | ||||
| 		WINDOWSSDK_LATEST_NAME) | ||||
| 	set(WINDOWSSDK_DIRS ${_win_sdk_dirs}) | ||||
|  | ||||
| 	# Fallback, in case no preference found. | ||||
| 	set(WINDOWSSDK_PREFERRED_DIR "${WINDOWSSDK_LATEST_DIR}") | ||||
| 	set(WINDOWSSDK_PREFERRED_NAME "${WINDOWSSDK_LATEST_NAME}") | ||||
| 	set(WINDOWSSDK_PREFERRED_FIRST_DIRS ${WINDOWSSDK_DIRS}) | ||||
| 	set(WINDOWSSDK_FOUND_PREFERENCE OFF) | ||||
| endif() | ||||
|  | ||||
| # If we found indications of a user preference... | ||||
| if(_win_sdk_preferred_sdk_dirs) | ||||
| 	list(GET _win_sdk_preferred_sdk_dirs 0 WINDOWSSDK_PREFERRED_DIR) | ||||
| 	windowssdk_name_lookup("${WINDOWSSDK_PREFERRED_DIR}" | ||||
| 		WINDOWSSDK_PREFERRED_NAME) | ||||
| 	set(WINDOWSSDK_PREFERRED_FIRST_DIRS | ||||
| 		${_win_sdk_preferred_sdk_dirs} | ||||
| 		${_win_sdk_dirs}) | ||||
| 	list(REMOVE_DUPLICATES WINDOWSSDK_PREFERRED_FIRST_DIRS) | ||||
| 	set(WINDOWSSDK_FOUND_PREFERENCE ON) | ||||
| endif() | ||||
|  | ||||
| include(FindPackageHandleStandardArgs) | ||||
| find_package_handle_standard_args(WindowsSDK | ||||
| 	"No compatible version of the Windows SDK or Platform SDK found." | ||||
| 	WINDOWSSDK_DIRS) | ||||
|  | ||||
| if(WINDOWSSDK_FOUND) | ||||
| 	# Internal: Architecture-appropriate library directory names. | ||||
| 	if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM") | ||||
| 		if(CMAKE_SIZEOF_VOID_P MATCHES "8") | ||||
| 			# Only supported in Win10 SDK and up. | ||||
| 			set(_winsdk_arch8 arm64) # what the WDK for Win8+ calls this architecture | ||||
| 		else() | ||||
| 			set(_winsdk_archbare /arm) # what the architecture used to be called in oldest SDKs | ||||
| 			set(_winsdk_arch arm) # what the architecture used to be called | ||||
| 			set(_winsdk_arch8 arm) # what the WDK for Win8+ calls this architecture | ||||
| 		endif() | ||||
| 	else() | ||||
| 		if(CMAKE_SIZEOF_VOID_P MATCHES "8") | ||||
| 			set(_winsdk_archbare /x64) # what the architecture used to be called in oldest SDKs | ||||
| 			set(_winsdk_arch amd64) # what the architecture used to be called | ||||
| 			set(_winsdk_arch8 x64) # what the WDK for Win8+ calls this architecture | ||||
| 		else() | ||||
| 			set(_winsdk_archbare ) # what the architecture used to be called in oldest SDKs | ||||
| 			set(_winsdk_arch i386) # what the architecture used to be called | ||||
| 			set(_winsdk_arch8 x86) # what the WDK for Win8+ calls this architecture | ||||
| 		endif() | ||||
| 	endif() | ||||
|  | ||||
| 	function(get_windowssdk_from_component _component _var) | ||||
| 		get_filename_component(_component "${_component}" ABSOLUTE) | ||||
| 		file(TO_CMAKE_PATH "${_component}" _component) | ||||
| 		foreach(_sdkdir ${WINDOWSSDK_DIRS}) | ||||
| 			get_filename_component(_sdkdir "${_sdkdir}" ABSOLUTE) | ||||
| 			string(LENGTH "${_sdkdir}" _sdklen) | ||||
| 			file(RELATIVE_PATH _rel "${_sdkdir}" "${_component}") | ||||
| 			# If we don't have any "parent directory" items... | ||||
| 			if(NOT "${_rel}" MATCHES "[.][.]") | ||||
| 				set(${_var} "${_sdkdir}" PARENT_SCOPE) | ||||
| 				return() | ||||
| 			endif() | ||||
| 		endforeach() | ||||
| 		# Fail. | ||||
| 		set(${_var} "NOTFOUND" PARENT_SCOPE) | ||||
| 	endfunction() | ||||
| 	function(get_windowssdk_library_dirs _winsdk_dir _var) | ||||
| 		set(_dirs) | ||||
| 		set(_suffixes | ||||
| 			"lib${_winsdk_archbare}" # SDKs like 7.1A | ||||
| 			"lib/${_winsdk_arch}" # just because some SDKs have x86 dir and root dir | ||||
| 			"lib/w2k/${_winsdk_arch}" # Win2k min requirement | ||||
| 			"lib/wxp/${_winsdk_arch}" # WinXP min requirement | ||||
| 			"lib/wnet/${_winsdk_arch}" # Win Server 2003 min requirement | ||||
| 			"lib/wlh/${_winsdk_arch}" | ||||
| 			"lib/wlh/um/${_winsdk_arch8}" # Win Vista ("Long Horn") min requirement | ||||
| 			"lib/win7/${_winsdk_arch}" | ||||
| 			"lib/win7/um/${_winsdk_arch8}" # Win 7 min requirement | ||||
| 		) | ||||
| 		foreach(_ver | ||||
| 			wlh # Win Vista ("Long Horn") min requirement | ||||
| 			win7 # Win 7 min requirement | ||||
| 			win8 # Win 8 min requirement | ||||
| 			winv6.3 # Win 8.1 min requirement | ||||
| 		) | ||||
|  | ||||
| 			list(APPEND _suffixes | ||||
| 				"lib/${_ver}/${_winsdk_arch}" | ||||
| 				"lib/${_ver}/um/${_winsdk_arch8}" | ||||
| 				"lib/${_ver}/km/${_winsdk_arch8}" | ||||
| 			) | ||||
| 		endforeach() | ||||
|  | ||||
| 		# Look for WDF libraries in Win10+ SDK | ||||
| 		foreach(_mode umdf kmdf) | ||||
| 			file(GLOB _wdfdirs RELATIVE "${_winsdk_dir}" "${_winsdk_dir}/lib/wdf/${_mode}/${_winsdk_arch8}/*") | ||||
| 			if(_wdfdirs) | ||||
| 				list(APPEND _suffixes ${_wdfdirs}) | ||||
| 			endif() | ||||
| 		endforeach() | ||||
|  | ||||
| 		# Look in each Win10+ SDK version for the components | ||||
| 		foreach(_win10ver ${_winsdk_win10vers}) | ||||
| 			foreach(_component um km ucrt mmos) | ||||
| 				list(APPEND _suffixes "lib/${_win10ver}/${_component}/${_winsdk_arch8}") | ||||
| 			endforeach() | ||||
| 		endforeach() | ||||
|  | ||||
| 		foreach(_suffix ${_suffixes}) | ||||
| 			# Check to see if a library actually exists here. | ||||
| 			file(GLOB _libs "${_winsdk_dir}/${_suffix}/*.lib") | ||||
| 			if(_libs) | ||||
| 				list(APPEND _dirs "${_winsdk_dir}/${_suffix}") | ||||
| 			endif() | ||||
| 		endforeach() | ||||
| 		if("${_dirs}" STREQUAL "") | ||||
| 			set(_dirs NOTFOUND) | ||||
| 		else() | ||||
| 			list(REMOVE_DUPLICATES _dirs) | ||||
| 		endif() | ||||
| 		set(${_var} ${_dirs} PARENT_SCOPE) | ||||
| 	endfunction() | ||||
| 	function(get_windowssdk_include_dirs _winsdk_dir _var) | ||||
| 		set(_dirs) | ||||
|  | ||||
| 		set(_subdirs shared um winrt km wdf mmos ucrt) | ||||
| 		set(_suffixes Include) | ||||
|  | ||||
| 		foreach(_dir ${_subdirs}) | ||||
| 			list(APPEND _suffixes "Include/${_dir}") | ||||
| 		endforeach() | ||||
|  | ||||
| 		foreach(_ver ${_winsdk_win10vers}) | ||||
| 			foreach(_dir ${_subdirs}) | ||||
| 				list(APPEND _suffixes "Include/${_ver}/${_dir}") | ||||
| 			endforeach() | ||||
| 		endforeach() | ||||
|  | ||||
| 		foreach(_suffix ${_suffixes}) | ||||
| 			# Check to see if a header file actually exists here. | ||||
| 			file(GLOB _headers "${_winsdk_dir}/${_suffix}/*.h") | ||||
| 			if(_headers) | ||||
| 				list(APPEND _dirs "${_winsdk_dir}/${_suffix}") | ||||
| 			endif() | ||||
| 		endforeach() | ||||
| 		if("${_dirs}" STREQUAL "") | ||||
| 			set(_dirs NOTFOUND) | ||||
| 		else() | ||||
| 			list(REMOVE_DUPLICATES _dirs) | ||||
| 		endif() | ||||
| 		set(${_var} ${_dirs} PARENT_SCOPE) | ||||
| 	endfunction() | ||||
| 	function(get_windowssdk_library_dirs_multiple _var) | ||||
| 		set(_dirs) | ||||
| 		foreach(_sdkdir ${ARGN}) | ||||
| 			get_windowssdk_library_dirs("${_sdkdir}" _current_sdk_libdirs) | ||||
| 			if(_current_sdk_libdirs) | ||||
| 				list(APPEND _dirs ${_current_sdk_libdirs}) | ||||
| 			endif() | ||||
| 		endforeach() | ||||
| 		if("${_dirs}" STREQUAL "") | ||||
| 			set(_dirs NOTFOUND) | ||||
| 		else() | ||||
| 			list(REMOVE_DUPLICATES _dirs) | ||||
| 		endif() | ||||
| 		set(${_var} ${_dirs} PARENT_SCOPE) | ||||
| 	endfunction() | ||||
| 	function(get_windowssdk_include_dirs_multiple _var) | ||||
| 		set(_dirs) | ||||
| 		foreach(_sdkdir ${ARGN}) | ||||
| 			get_windowssdk_include_dirs("${_sdkdir}" _current_sdk_incdirs) | ||||
| 			if(_current_sdk_libdirs) | ||||
| 				list(APPEND _dirs ${_current_sdk_incdirs}) | ||||
| 			endif() | ||||
| 		endforeach() | ||||
| 		if("${_dirs}" STREQUAL "") | ||||
| 			set(_dirs NOTFOUND) | ||||
| 		else() | ||||
| 			list(REMOVE_DUPLICATES _dirs) | ||||
| 		endif() | ||||
| 		set(${_var} ${_dirs} PARENT_SCOPE) | ||||
| 	endfunction() | ||||
| endif() | ||||
							
								
								
									
										
											BIN
										
									
								
								cmake/nsis/hyperion-logo-vert.bmp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								cmake/nsis/hyperion-logo-vert.bmp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 151 KiB | 
							
								
								
									
										
											BIN
										
									
								
								cmake/nsis/hyperion-logo.bmp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								cmake/nsis/hyperion-logo.bmp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 86 KiB | 
							
								
								
									
										1
									
								
								cmake/nsis/icon.rc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								cmake/nsis/icon.rc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| IDI_ICON1 ICON DISCARDABLE "installer.ico" | ||||
							
								
								
									
										
											BIN
										
									
								
								cmake/nsis/installer.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								cmake/nsis/installer.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 87 KiB | 
							
								
								
									
										46
									
								
								cmake/nsis/template/NSIS.InstallOptions.ini.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								cmake/nsis/template/NSIS.InstallOptions.ini.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| [Settings] | ||||
| NumFields=5 | ||||
|  | ||||
| [Field 1] | ||||
| Type=label | ||||
| Text=By default @CPACK_PACKAGE_INSTALL_DIRECTORY@ does not add its directory to the system PATH. | ||||
| Left=0 | ||||
| Right=-1 | ||||
| Top=0 | ||||
| Bottom=20 | ||||
|  | ||||
| [Field 2] | ||||
| Type=radiobutton | ||||
| Text=Do not add @CPACK_PACKAGE_NAME@ to the system PATH | ||||
| Left=0 | ||||
| Right=-1 | ||||
| Top=30 | ||||
| Bottom=40 | ||||
| State=1 | ||||
|  | ||||
| [Field 3] | ||||
| Type=radiobutton | ||||
| Text=Add @CPACK_PACKAGE_NAME@ to the system PATH for all users | ||||
| Left=0 | ||||
| Right=-1 | ||||
| Top=40 | ||||
| Bottom=50 | ||||
| State=0 | ||||
|  | ||||
| [Field 4] | ||||
| Type=radiobutton | ||||
| Text=Add @CPACK_PACKAGE_NAME@ to the system PATH for current user | ||||
| Left=0 | ||||
| Right=-1 | ||||
| Top=50 | ||||
| Bottom=60 | ||||
| State=0 | ||||
|  | ||||
| [Field 5] | ||||
| Type=CheckBox | ||||
| Text=Create @CPACK_PACKAGE_NAME@ Desktop Icon | ||||
| Left=0 | ||||
| Right=-1 | ||||
| Top=80 | ||||
| Bottom=90 | ||||
| State=1 | ||||
							
								
								
									
										978
									
								
								cmake/nsis/template/NSIS.template.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										978
									
								
								cmake/nsis/template/NSIS.template.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,978 @@ | ||||
| ; CPack install script designed for a nmake build | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; You must define these values | ||||
|  | ||||
|   !define VERSION "@CPACK_PACKAGE_VERSION@" | ||||
|   !define PATCH  "@CPACK_PACKAGE_VERSION_PATCH@" | ||||
|   !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@" | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;Variables | ||||
|  | ||||
|   Var MUI_TEMP | ||||
|   Var STARTMENU_FOLDER | ||||
|   Var SV_ALLUSERS | ||||
|   Var START_MENU | ||||
|   Var DO_NOT_ADD_TO_PATH | ||||
|   Var ADD_TO_PATH_ALL_USERS | ||||
|   Var ADD_TO_PATH_CURRENT_USER | ||||
|   Var INSTALL_DESKTOP | ||||
|   Var IS_DEFAULT_INSTALLDIR | ||||
| ;-------------------------------- | ||||
| ;Include Modern UI | ||||
|  | ||||
|   !include "MUI.nsh" | ||||
|  | ||||
|   ;Default installation folder | ||||
|   InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;General | ||||
|  | ||||
|   ;Name and file | ||||
|   Name "@CPACK_NSIS_PACKAGE_NAME@" | ||||
|   OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" | ||||
|  | ||||
|   ;Set compression | ||||
|   SetCompressor @CPACK_NSIS_COMPRESSOR@ | ||||
|  | ||||
|   ;Require administrator access | ||||
|   RequestExecutionLevel admin | ||||
|  | ||||
| @CPACK_NSIS_DEFINES@ | ||||
|  | ||||
|   !include Sections.nsh | ||||
|  | ||||
| ;--- Component support macros: --- | ||||
| ; The code for the add/remove functionality is from: | ||||
| ;   http://nsis.sourceforge.net/Add/Remove_Functionality | ||||
| ; It has been modified slightly and extended to provide | ||||
| ; inter-component dependencies. | ||||
| Var AR_SecFlags | ||||
| Var AR_RegFlags | ||||
| @CPACK_NSIS_SECTION_SELECTED_VARS@ | ||||
|  | ||||
| ; Loads the "selected" flag for the section named SecName into the | ||||
| ; variable VarName. | ||||
| !macro LoadSectionSelectedIntoVar SecName VarName | ||||
|  SectionGetFlags ${${SecName}} $${VarName} | ||||
|  IntOp $${VarName} $${VarName} & ${SF_SELECTED}  ;Turn off all other bits | ||||
| !macroend | ||||
|  | ||||
| ; Loads the value of a variable... can we get around this? | ||||
| !macro LoadVar VarName | ||||
|   IntOp $R0 0 + $${VarName} | ||||
| !macroend | ||||
|  | ||||
| ; Sets the value of a variable | ||||
| !macro StoreVar VarName IntValue | ||||
|   IntOp $${VarName} 0 + ${IntValue} | ||||
| !macroend | ||||
|  | ||||
| !macro InitSection SecName | ||||
|   ;  This macro reads component installed flag from the registry and | ||||
|   ;changes checked state of the section on the components page. | ||||
|   ;Input: section index constant name specified in Section command. | ||||
|  | ||||
|   ClearErrors | ||||
|   ;Reading component status from registry | ||||
|   ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed" | ||||
|   IfErrors "default_${SecName}" | ||||
|     ;Status will stay default if registry value not found | ||||
|     ;(component was never installed) | ||||
|   IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits | ||||
|   SectionGetFlags ${${SecName}} $AR_SecFlags  ;Reading default section flags | ||||
|   IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE  ;Turn lowest (enabled) bit off | ||||
|   IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags      ;Change lowest bit | ||||
|  | ||||
|   ; Note whether this component was installed before | ||||
|   !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags | ||||
|   IntOp $R0 $AR_RegFlags & $AR_RegFlags | ||||
|  | ||||
|   ;Writing modified flags | ||||
|   SectionSetFlags ${${SecName}} $AR_SecFlags | ||||
|  | ||||
|  "default_${SecName}:" | ||||
|  !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected | ||||
| !macroend | ||||
|  | ||||
| !macro FinishSection SecName | ||||
|   ;  This macro reads section flag set by user and removes the section | ||||
|   ;if it is not selected. | ||||
|   ;Then it writes component installed flag to registry | ||||
|   ;Input: section index constant name specified in Section command. | ||||
|  | ||||
|   SectionGetFlags ${${SecName}} $AR_SecFlags  ;Reading section flags | ||||
|   ;Checking lowest bit: | ||||
|   IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED} | ||||
|   IntCmp $AR_SecFlags 1 "leave_${SecName}" | ||||
|     ;Section is not selected: | ||||
|     ;Calling Section uninstall macro and writing zero installed flag | ||||
|     !insertmacro "Remove_${${SecName}}" | ||||
|     WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ | ||||
|   "Installed" 0 | ||||
|     Goto "exit_${SecName}" | ||||
|  | ||||
|  "leave_${SecName}:" | ||||
|     ;Section is selected: | ||||
|     WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ | ||||
|   "Installed" 1 | ||||
|  | ||||
|  "exit_${SecName}:" | ||||
| !macroend | ||||
|  | ||||
| !macro RemoveSection_CPack SecName | ||||
|   ;  This macro is used to call section's Remove_... macro | ||||
|   ;from the uninstaller. | ||||
|   ;Input: section index constant name specified in Section command. | ||||
|  | ||||
|   !insertmacro "Remove_${${SecName}}" | ||||
| !macroend | ||||
|  | ||||
| ; Determine whether the selection of SecName changed | ||||
| !macro MaybeSelectionChanged SecName | ||||
|   !insertmacro LoadVar ${SecName}_selected | ||||
|   SectionGetFlags ${${SecName}} $R1 | ||||
|   IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits | ||||
|  | ||||
|   ; See if the status has changed: | ||||
|   IntCmp $R0 $R1 "${SecName}_unchanged" | ||||
|   !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected | ||||
|  | ||||
|   IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected" | ||||
|   !insertmacro "Deselect_required_by_${SecName}" | ||||
|   goto "${SecName}_unchanged" | ||||
|  | ||||
|   "${SecName}_was_selected:" | ||||
|   !insertmacro "Select_${SecName}_depends" | ||||
|  | ||||
|   "${SecName}_unchanged:" | ||||
| !macroend | ||||
| ;--- End of Add/Remove macros --- | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;Interface Settings | ||||
|  | ||||
|   !define MUI_HEADERIMAGE | ||||
|   !define MUI_ABORTWARNING | ||||
|  | ||||
| ;---------------------------------------- | ||||
| ; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02" | ||||
| ;---------------------------------------- | ||||
| !verbose 3 | ||||
| !include "WinMessages.NSH" | ||||
| !verbose 4 | ||||
| ;==================================================== | ||||
| ; get_NT_environment | ||||
| ;     Returns: the selected environment | ||||
| ;     Output : head of the stack | ||||
| ;==================================================== | ||||
| !macro select_NT_profile UN | ||||
| Function ${UN}select_NT_profile | ||||
|    StrCmp $ADD_TO_PATH_ALL_USERS "1" 0 environment_single | ||||
|       DetailPrint "Selected environment for all users" | ||||
|       Push "all" | ||||
|       Return | ||||
|    environment_single: | ||||
|       DetailPrint "Selected environment for current user only." | ||||
|       Push "current" | ||||
|       Return | ||||
| FunctionEnd | ||||
| !macroend | ||||
| !insertmacro select_NT_profile "" | ||||
| !insertmacro select_NT_profile "un." | ||||
| ;---------------------------------------------------- | ||||
| !define NT_current_env 'HKCU "Environment"' | ||||
| !define NT_all_env     'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' | ||||
|  | ||||
| !ifndef WriteEnvStr_RegKey | ||||
|   !ifdef ALL_USERS | ||||
|     !define WriteEnvStr_RegKey \ | ||||
|        'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' | ||||
|   !else | ||||
|     !define WriteEnvStr_RegKey 'HKCU "Environment"' | ||||
|   !endif | ||||
| !endif | ||||
|  | ||||
| ; AddToPath - Adds the given dir to the search path. | ||||
| ;        Input - head of the stack | ||||
| ;        Note - Win9x systems requires reboot | ||||
|  | ||||
| Function AddToPath | ||||
|   Exch $0 | ||||
|   Push $1 | ||||
|   Push $2 | ||||
|   Push $3 | ||||
|  | ||||
|   # don't add if the path doesn't exist | ||||
|   IfFileExists "$0\*.*" "" AddToPath_done | ||||
|  | ||||
|   ReadEnvStr $1 PATH | ||||
|   ; if the path is too long for a NSIS variable NSIS will return a 0 | ||||
|   ; length string.  If we find that, then warn and skip any path | ||||
|   ; modification as it will trash the existing path. | ||||
|   StrLen $2 $1 | ||||
|   IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done | ||||
|     CheckPathLength_ShowPathWarning: | ||||
|     Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!" | ||||
|     Goto AddToPath_done | ||||
|   CheckPathLength_Done: | ||||
|   Push "$1;" | ||||
|   Push "$0;" | ||||
|   Call StrStr | ||||
|   Pop $2 | ||||
|   StrCmp $2 "" "" AddToPath_done | ||||
|   Push "$1;" | ||||
|   Push "$0\;" | ||||
|   Call StrStr | ||||
|   Pop $2 | ||||
|   StrCmp $2 "" "" AddToPath_done | ||||
|   GetFullPathName /SHORT $3 $0 | ||||
|   Push "$1;" | ||||
|   Push "$3;" | ||||
|   Call StrStr | ||||
|   Pop $2 | ||||
|   StrCmp $2 "" "" AddToPath_done | ||||
|   Push "$1;" | ||||
|   Push "$3\;" | ||||
|   Call StrStr | ||||
|   Pop $2 | ||||
|   StrCmp $2 "" "" AddToPath_done | ||||
|  | ||||
|   Call IsNT | ||||
|   Pop $1 | ||||
|   StrCmp $1 1 AddToPath_NT | ||||
|     ; Not on NT | ||||
|     StrCpy $1 $WINDIR 2 | ||||
|     FileOpen $1 "$1\autoexec.bat" a | ||||
|     FileSeek $1 -1 END | ||||
|     FileReadByte $1 $2 | ||||
|     IntCmp $2 26 0 +2 +2 # DOS EOF | ||||
|       FileSeek $1 -1 END # write over EOF | ||||
|     FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n" | ||||
|     FileClose $1 | ||||
|     SetRebootFlag true | ||||
|     Goto AddToPath_done | ||||
|  | ||||
|   AddToPath_NT: | ||||
|     StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey | ||||
|       ReadRegStr $1 ${NT_current_env} "PATH" | ||||
|       Goto DoTrim | ||||
|     ReadAllKey: | ||||
|       ReadRegStr $1 ${NT_all_env} "PATH" | ||||
|     DoTrim: | ||||
|     StrCmp $1 "" AddToPath_NTdoIt | ||||
|       Push $1 | ||||
|       Call Trim | ||||
|       Pop $1 | ||||
|       StrCpy $0 "$1;$0" | ||||
|     AddToPath_NTdoIt: | ||||
|       StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey | ||||
|         WriteRegExpandStr ${NT_current_env} "PATH" $0 | ||||
|         Goto DoSend | ||||
|       WriteAllKey: | ||||
|         WriteRegExpandStr ${NT_all_env} "PATH" $0 | ||||
|       DoSend: | ||||
|       SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 | ||||
|  | ||||
|   AddToPath_done: | ||||
|     Pop $3 | ||||
|     Pop $2 | ||||
|     Pop $1 | ||||
|     Pop $0 | ||||
| FunctionEnd | ||||
|  | ||||
|  | ||||
| ; RemoveFromPath - Remove a given dir from the path | ||||
| ;     Input: head of the stack | ||||
|  | ||||
| Function un.RemoveFromPath | ||||
|   Exch $0 | ||||
|   Push $1 | ||||
|   Push $2 | ||||
|   Push $3 | ||||
|   Push $4 | ||||
|   Push $5 | ||||
|   Push $6 | ||||
|  | ||||
|   IntFmt $6 "%c" 26 # DOS EOF | ||||
|  | ||||
|   Call un.IsNT | ||||
|   Pop $1 | ||||
|   StrCmp $1 1 unRemoveFromPath_NT | ||||
|     ; Not on NT | ||||
|     StrCpy $1 $WINDIR 2 | ||||
|     FileOpen $1 "$1\autoexec.bat" r | ||||
|     GetTempFileName $4 | ||||
|     FileOpen $2 $4 w | ||||
|     GetFullPathName /SHORT $0 $0 | ||||
|     StrCpy $0 "SET PATH=%PATH%;$0" | ||||
|     Goto unRemoveFromPath_dosLoop | ||||
|  | ||||
|     unRemoveFromPath_dosLoop: | ||||
|       FileRead $1 $3 | ||||
|       StrCpy $5 $3 1 -1 # read last char | ||||
|       StrCmp $5 $6 0 +2 # if DOS EOF | ||||
|         StrCpy $3 $3 -1 # remove DOS EOF so we can compare | ||||
|       StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine | ||||
|       StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine | ||||
|       StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine | ||||
|       StrCmp $3 "" unRemoveFromPath_dosLoopEnd | ||||
|       FileWrite $2 $3 | ||||
|       Goto unRemoveFromPath_dosLoop | ||||
|       unRemoveFromPath_dosLoopRemoveLine: | ||||
|         SetRebootFlag true | ||||
|         Goto unRemoveFromPath_dosLoop | ||||
|  | ||||
|     unRemoveFromPath_dosLoopEnd: | ||||
|       FileClose $2 | ||||
|       FileClose $1 | ||||
|       StrCpy $1 $WINDIR 2 | ||||
|       Delete "$1\autoexec.bat" | ||||
|       CopyFiles /SILENT $4 "$1\autoexec.bat" | ||||
|       Delete $4 | ||||
|       Goto unRemoveFromPath_done | ||||
|  | ||||
|   unRemoveFromPath_NT: | ||||
|     StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey | ||||
|       ReadRegStr $1 ${NT_current_env} "PATH" | ||||
|       Goto unDoTrim | ||||
|     unReadAllKey: | ||||
|       ReadRegStr $1 ${NT_all_env} "PATH" | ||||
|     unDoTrim: | ||||
|     StrCpy $5 $1 1 -1 # copy last char | ||||
|     StrCmp $5 ";" +2 # if last char != ; | ||||
|       StrCpy $1 "$1;" # append ; | ||||
|     Push $1 | ||||
|     Push "$0;" | ||||
|     Call un.StrStr ; Find `$0;` in $1 | ||||
|     Pop $2 ; pos of our dir | ||||
|     StrCmp $2 "" unRemoveFromPath_done | ||||
|       ; else, it is in path | ||||
|       # $0 - path to add | ||||
|       # $1 - path var | ||||
|       StrLen $3 "$0;" | ||||
|       StrLen $4 $2 | ||||
|       StrCpy $5 $1 -$4 # $5 is now the part before the path to remove | ||||
|       StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove | ||||
|       StrCpy $3 $5$6 | ||||
|  | ||||
|       StrCpy $5 $3 1 -1 # copy last char | ||||
|       StrCmp $5 ";" 0 +2 # if last char == ; | ||||
|         StrCpy $3 $3 -1 # remove last char | ||||
|  | ||||
|       StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey | ||||
|         WriteRegExpandStr ${NT_current_env} "PATH" $3 | ||||
|         Goto unDoSend | ||||
|       unWriteAllKey: | ||||
|         WriteRegExpandStr ${NT_all_env} "PATH" $3 | ||||
|       unDoSend: | ||||
|       SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 | ||||
|  | ||||
|   unRemoveFromPath_done: | ||||
|     Pop $6 | ||||
|     Pop $5 | ||||
|     Pop $4 | ||||
|     Pop $3 | ||||
|     Pop $2 | ||||
|     Pop $1 | ||||
|     Pop $0 | ||||
| FunctionEnd | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ; Uninstall sutff | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| ########################################### | ||||
| #            Utility Functions            # | ||||
| ########################################### | ||||
|  | ||||
| ;==================================================== | ||||
| ; IsNT - Returns 1 if the current system is NT, 0 | ||||
| ;        otherwise. | ||||
| ;     Output: head of the stack | ||||
| ;==================================================== | ||||
| ; IsNT | ||||
| ; no input | ||||
| ; output, top of the stack = 1 if NT or 0 if not | ||||
| ; | ||||
| ; Usage: | ||||
| ;   Call IsNT | ||||
| ;   Pop $R0 | ||||
| ;  ($R0 at this point is 1 or 0) | ||||
|  | ||||
| !macro IsNT un | ||||
| Function ${un}IsNT | ||||
|   Push $0 | ||||
|   ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion | ||||
|   StrCmp $0 "" 0 IsNT_yes | ||||
|   ; we are not NT. | ||||
|   Pop $0 | ||||
|   Push 0 | ||||
|   Return | ||||
|  | ||||
|   IsNT_yes: | ||||
|     ; NT!!! | ||||
|     Pop $0 | ||||
|     Push 1 | ||||
| FunctionEnd | ||||
| !macroend | ||||
| !insertmacro IsNT "" | ||||
| !insertmacro IsNT "un." | ||||
|  | ||||
| ; StrStr | ||||
| ; input, top of stack = string to search for | ||||
| ;        top of stack-1 = string to search in | ||||
| ; output, top of stack (replaces with the portion of the string remaining) | ||||
| ; modifies no other variables. | ||||
| ; | ||||
| ; Usage: | ||||
| ;   Push "this is a long ass string" | ||||
| ;   Push "ass" | ||||
| ;   Call StrStr | ||||
| ;   Pop $R0 | ||||
| ;  ($R0 at this point is "ass string") | ||||
|  | ||||
| !macro StrStr un | ||||
| Function ${un}StrStr | ||||
| Exch $R1 ; st=haystack,old$R1, $R1=needle | ||||
|   Exch    ; st=old$R1,haystack | ||||
|   Exch $R2 ; st=old$R1,old$R2, $R2=haystack | ||||
|   Push $R3 | ||||
|   Push $R4 | ||||
|   Push $R5 | ||||
|   StrLen $R3 $R1 | ||||
|   StrCpy $R4 0 | ||||
|   ; $R1=needle | ||||
|   ; $R2=haystack | ||||
|   ; $R3=len(needle) | ||||
|   ; $R4=cnt | ||||
|   ; $R5=tmp | ||||
|   loop: | ||||
|     StrCpy $R5 $R2 $R3 $R4 | ||||
|     StrCmp $R5 $R1 done | ||||
|     StrCmp $R5 "" done | ||||
|     IntOp $R4 $R4 + 1 | ||||
|     Goto loop | ||||
| done: | ||||
|   StrCpy $R1 $R2 "" $R4 | ||||
|   Pop $R5 | ||||
|   Pop $R4 | ||||
|   Pop $R3 | ||||
|   Pop $R2 | ||||
|   Exch $R1 | ||||
| FunctionEnd | ||||
| !macroend | ||||
| !insertmacro StrStr "" | ||||
| !insertmacro StrStr "un." | ||||
|  | ||||
| Function Trim ; Added by Pelaca | ||||
| 	Exch $R1 | ||||
| 	Push $R2 | ||||
| Loop: | ||||
| 	StrCpy $R2 "$R1" 1 -1 | ||||
| 	StrCmp "$R2" " " RTrim | ||||
| 	StrCmp "$R2" "$\n" RTrim | ||||
| 	StrCmp "$R2" "$\r" RTrim | ||||
| 	StrCmp "$R2" ";" RTrim | ||||
| 	GoTo Done | ||||
| RTrim: | ||||
| 	StrCpy $R1 "$R1" -1 | ||||
| 	Goto Loop | ||||
| Done: | ||||
| 	Pop $R2 | ||||
| 	Exch $R1 | ||||
| FunctionEnd | ||||
|  | ||||
| Function ConditionalAddToRegisty | ||||
|   Pop $0 | ||||
|   Pop $1 | ||||
|   StrCmp "$0" "" ConditionalAddToRegisty_EmptyString | ||||
|     WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ | ||||
|     "$1" "$0" | ||||
|     ;MessageBox MB_OK "Set Registry: '$1' to '$0'" | ||||
|     DetailPrint "Set install registry entry: '$1' to '$0'" | ||||
|   ConditionalAddToRegisty_EmptyString: | ||||
| FunctionEnd | ||||
|  | ||||
| ;-------------------------------- | ||||
|  | ||||
| !ifdef CPACK_USES_DOWNLOAD | ||||
| Function DownloadFile | ||||
|     IfFileExists $INSTDIR\* +2 | ||||
|     CreateDirectory $INSTDIR | ||||
|     Pop $0 | ||||
|  | ||||
|     ; Skip if already downloaded | ||||
|     IfFileExists $INSTDIR\$0 0 +2 | ||||
|     Return | ||||
|  | ||||
|     StrCpy $1 "@CPACK_DOWNLOAD_SITE@" | ||||
|  | ||||
|   try_again: | ||||
|     NSISdl::download "$1/$0" "$INSTDIR\$0" | ||||
|  | ||||
|     Pop $1 | ||||
|     StrCmp $1 "success" success | ||||
|     StrCmp $1 "Cancelled" cancel | ||||
|     MessageBox MB_OK "Download failed: $1" | ||||
|   cancel: | ||||
|     Return | ||||
|   success: | ||||
| FunctionEnd | ||||
| !endif | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; Define some macro setting for the gui | ||||
| @CPACK_NSIS_INSTALLER_MUI_ICON_CODE@ | ||||
| @CPACK_NSIS_INSTALLER_ICON_CODE@ | ||||
| @CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE@ | ||||
| @CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE@ | ||||
| @CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@ | ||||
| @CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@ | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;Pages | ||||
|   @CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE@ | ||||
|   @CPACK_NSIS_INSTALLER_WELCOME_TITLE_3LINES_CODE@ | ||||
|   !insertmacro MUI_PAGE_WELCOME | ||||
|  | ||||
|   !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@" | ||||
|   Page custom InstallOptionsPage | ||||
|   !insertmacro MUI_PAGE_DIRECTORY | ||||
|  | ||||
|   ;Start Menu Folder Page Configuration | ||||
|   !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX" | ||||
|   !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" | ||||
|   !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" | ||||
|   !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER | ||||
|  | ||||
|   @CPACK_NSIS_PAGE_COMPONENTS@ | ||||
|  | ||||
|   !insertmacro MUI_PAGE_INSTFILES | ||||
|   @CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE@ | ||||
|   @CPACK_NSIS_INSTALLER_FINISH_TITLE_3LINES_CODE@ | ||||
|   !insertmacro MUI_PAGE_FINISH | ||||
|  | ||||
|   !insertmacro MUI_UNPAGE_CONFIRM | ||||
|   !insertmacro MUI_UNPAGE_INSTFILES | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;Languages | ||||
|  | ||||
|   !insertmacro MUI_LANGUAGE "English" ;first language is the default language | ||||
|   !insertmacro MUI_LANGUAGE "Albanian" | ||||
|   !insertmacro MUI_LANGUAGE "Arabic" | ||||
|   !insertmacro MUI_LANGUAGE "Basque" | ||||
|   !insertmacro MUI_LANGUAGE "Belarusian" | ||||
|   !insertmacro MUI_LANGUAGE "Bosnian" | ||||
|   !insertmacro MUI_LANGUAGE "Breton" | ||||
|   !insertmacro MUI_LANGUAGE "Bulgarian" | ||||
|   !insertmacro MUI_LANGUAGE "Croatian" | ||||
|   !insertmacro MUI_LANGUAGE "Czech" | ||||
|   !insertmacro MUI_LANGUAGE "Danish" | ||||
|   !insertmacro MUI_LANGUAGE "Dutch" | ||||
|   !insertmacro MUI_LANGUAGE "Estonian" | ||||
|   !insertmacro MUI_LANGUAGE "Farsi" | ||||
|   !insertmacro MUI_LANGUAGE "Finnish" | ||||
|   !insertmacro MUI_LANGUAGE "French" | ||||
|   !insertmacro MUI_LANGUAGE "German" | ||||
|   !insertmacro MUI_LANGUAGE "Greek" | ||||
|   !insertmacro MUI_LANGUAGE "Hebrew" | ||||
|   !insertmacro MUI_LANGUAGE "Hungarian" | ||||
|   !insertmacro MUI_LANGUAGE "Icelandic" | ||||
|   !insertmacro MUI_LANGUAGE "Indonesian" | ||||
|   !insertmacro MUI_LANGUAGE "Irish" | ||||
|   !insertmacro MUI_LANGUAGE "Italian" | ||||
|   !insertmacro MUI_LANGUAGE "Japanese" | ||||
|   !insertmacro MUI_LANGUAGE "Korean" | ||||
|   !insertmacro MUI_LANGUAGE "Kurdish" | ||||
|   !insertmacro MUI_LANGUAGE "Latvian" | ||||
|   !insertmacro MUI_LANGUAGE "Lithuanian" | ||||
|   !insertmacro MUI_LANGUAGE "Luxembourgish" | ||||
|   !insertmacro MUI_LANGUAGE "Macedonian" | ||||
|   !insertmacro MUI_LANGUAGE "Malay" | ||||
|   !insertmacro MUI_LANGUAGE "Mongolian" | ||||
|   !insertmacro MUI_LANGUAGE "Norwegian" | ||||
|   !insertmacro MUI_LANGUAGE "Polish" | ||||
|   !insertmacro MUI_LANGUAGE "Portuguese" | ||||
|   !insertmacro MUI_LANGUAGE "PortugueseBR" | ||||
|   !insertmacro MUI_LANGUAGE "Romanian" | ||||
|   !insertmacro MUI_LANGUAGE "Russian" | ||||
|   !insertmacro MUI_LANGUAGE "Serbian" | ||||
|   !insertmacro MUI_LANGUAGE "SerbianLatin" | ||||
|   !insertmacro MUI_LANGUAGE "SimpChinese" | ||||
|   !insertmacro MUI_LANGUAGE "Slovak" | ||||
|   !insertmacro MUI_LANGUAGE "Slovenian" | ||||
|   !insertmacro MUI_LANGUAGE "Spanish" | ||||
|   !insertmacro MUI_LANGUAGE "Swedish" | ||||
|   !insertmacro MUI_LANGUAGE "Thai" | ||||
|   !insertmacro MUI_LANGUAGE "TradChinese" | ||||
|   !insertmacro MUI_LANGUAGE "Turkish" | ||||
|   !insertmacro MUI_LANGUAGE "Ukrainian" | ||||
|   !insertmacro MUI_LANGUAGE "Welsh" | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;Reserve Files | ||||
|  | ||||
|   ;These files should be inserted before other files in the data block | ||||
|   ;Keep these lines before any File command | ||||
|   ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA) | ||||
|  | ||||
|   ReserveFile "NSIS.InstallOptions.ini" | ||||
|   !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS | ||||
|  | ||||
|   ; for UserInfo::GetName and UserInfo::GetAccountType | ||||
|   ReserveFile /plugin 'UserInfo.dll' | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; Installation types | ||||
| @CPACK_NSIS_INSTALLATION_TYPES@ | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; Component sections | ||||
| @CPACK_NSIS_COMPONENT_SECTIONS@ | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;Installer Sections | ||||
|  | ||||
| Section "-Core installation" | ||||
|   ;Use the entire tree produced by the INSTALL target.  Keep the | ||||
|   ;list of directories here in sync with the RMDir commands below. | ||||
|   SetOutPath "$INSTDIR" | ||||
|   @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ | ||||
|   @CPACK_NSIS_FULL_INSTALL@ | ||||
|  | ||||
|   ;Store installation folder | ||||
|   WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR | ||||
|  | ||||
|   ;Create uninstaller | ||||
|   WriteUninstaller "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" | ||||
|   Push "DisplayName" | ||||
|   Push "@CPACK_NSIS_DISPLAY_NAME@" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "DisplayVersion" | ||||
|   Push "@CPACK_PACKAGE_VERSION@" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "Publisher" | ||||
|   Push "@CPACK_PACKAGE_VENDOR@" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "UninstallString" | ||||
|   Push "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "NoRepair" | ||||
|   Push "1" | ||||
|   Call ConditionalAddToRegisty | ||||
|  | ||||
|   !ifdef CPACK_NSIS_ADD_REMOVE | ||||
|   ;Create add/remove functionality | ||||
|   Push "ModifyPath" | ||||
|   Push "$INSTDIR\AddRemove.exe" | ||||
|   Call ConditionalAddToRegisty | ||||
|   !else | ||||
|   Push "NoModify" | ||||
|   Push "1" | ||||
|   Call ConditionalAddToRegisty | ||||
|   !endif | ||||
|  | ||||
|   ; Optional registration | ||||
|   Push "DisplayIcon" | ||||
|   Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "HelpLink" | ||||
|   Push "@CPACK_NSIS_HELP_LINK@" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "URLInfoAbout" | ||||
|   Push "@CPACK_NSIS_URL_INFO_ABOUT@" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "Contact" | ||||
|   Push "@CPACK_NSIS_CONTACT@" | ||||
|   Call ConditionalAddToRegisty | ||||
|   !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State" | ||||
|   !insertmacro MUI_STARTMENU_WRITE_BEGIN Application | ||||
|  | ||||
|   ;Create shortcuts | ||||
|   CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" | ||||
| @CPACK_NSIS_CREATE_ICONS@ | ||||
| @CPACK_NSIS_CREATE_ICONS_EXTRA@ | ||||
|   CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" | ||||
|  | ||||
|   ;Read a value from an InstallOptions INI file | ||||
|   !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State" | ||||
|   !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State" | ||||
|   !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State" | ||||
|  | ||||
|   ; Write special uninstall registry entries | ||||
|   Push "StartMenu" | ||||
|   Push "$STARTMENU_FOLDER" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "DoNotAddToPath" | ||||
|   Push "$DO_NOT_ADD_TO_PATH" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "AddToPathAllUsers" | ||||
|   Push "$ADD_TO_PATH_ALL_USERS" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "AddToPathCurrentUser" | ||||
|   Push "$ADD_TO_PATH_CURRENT_USER" | ||||
|   Call ConditionalAddToRegisty | ||||
|   Push "InstallToDesktop" | ||||
|   Push "$INSTALL_DESKTOP" | ||||
|   Call ConditionalAddToRegisty | ||||
|  | ||||
|   !insertmacro MUI_STARTMENU_WRITE_END | ||||
|  | ||||
| @CPACK_NSIS_EXTRA_INSTALL_COMMANDS@ | ||||
|  | ||||
| SectionEnd | ||||
|  | ||||
| Section "-Add to path" | ||||
|   Push $INSTDIR\bin | ||||
|   StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 doNotAddToPath | ||||
|   StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0 | ||||
|     Call AddToPath | ||||
|   doNotAddToPath: | ||||
| SectionEnd | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; Create custom pages | ||||
| Function InstallOptionsPage | ||||
|   !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@" | ||||
|   !insertmacro MUI_INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini" | ||||
|  | ||||
| FunctionEnd | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; determine admin versus local install | ||||
| Function un.onInit | ||||
|  | ||||
|   ClearErrors | ||||
|   UserInfo::GetName | ||||
|   IfErrors noLM | ||||
|   Pop $0 | ||||
|   UserInfo::GetAccountType | ||||
|   Pop $1 | ||||
|   StrCmp $1 "Admin" 0 +3 | ||||
|     SetShellVarContext all | ||||
|     ;MessageBox MB_OK 'User "$0" is in the Admin group' | ||||
|     Goto done | ||||
|   StrCmp $1 "Power" 0 +3 | ||||
|     SetShellVarContext all | ||||
|     ;MessageBox MB_OK 'User "$0" is in the Power Users group' | ||||
|     Goto done | ||||
|  | ||||
|   noLM: | ||||
|     ;Get installation folder from registry if available | ||||
|  | ||||
|   done: | ||||
|  | ||||
| FunctionEnd | ||||
|  | ||||
| ;--- Add/Remove callback functions: --- | ||||
| !macro SectionList MacroName | ||||
|   ;This macro used to perform operation on multiple sections. | ||||
|   ;List all of your components in following manner here. | ||||
| @CPACK_NSIS_COMPONENT_SECTION_LIST@ | ||||
| !macroend | ||||
|  | ||||
| Section -FinishComponents | ||||
|   ;Removes unselected components and writes component status to registry | ||||
|   !insertmacro SectionList "FinishSection" | ||||
|  | ||||
| !ifdef CPACK_NSIS_ADD_REMOVE | ||||
|   ; Get the name of the installer executable | ||||
|   System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1' | ||||
|   StrCpy $R3 $R0 | ||||
|  | ||||
|   ; Strip off the last 13 characters, to see if we have AddRemove.exe | ||||
|   StrLen $R1 $R0 | ||||
|   IntOp $R1 $R0 - 13 | ||||
|   StrCpy $R2 $R0 13 $R1 | ||||
|   StrCmp $R2 "AddRemove.exe" addremove_installed | ||||
|  | ||||
|   ; We're not running AddRemove.exe, so install it | ||||
|   CopyFiles $R3 $INSTDIR\AddRemove.exe | ||||
|  | ||||
|   addremove_installed: | ||||
| !endif | ||||
| SectionEnd | ||||
| ;--- End of Add/Remove callback functions --- | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; Component dependencies | ||||
| Function .onSelChange | ||||
|   !insertmacro SectionList MaybeSelectionChanged | ||||
| FunctionEnd | ||||
|  | ||||
| ;-------------------------------- | ||||
| ;Uninstaller Section | ||||
|  | ||||
| Section "Uninstall" | ||||
|   ReadRegStr $START_MENU SHCTX \ | ||||
|    "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu" | ||||
|   ;MessageBox MB_OK "Start menu is in: $START_MENU" | ||||
|   ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \ | ||||
|     "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath" | ||||
|   ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \ | ||||
|     "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers" | ||||
|   ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \ | ||||
|     "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser" | ||||
|   ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS" | ||||
|   ReadRegStr $INSTALL_DESKTOP SHCTX \ | ||||
|     "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop" | ||||
|   ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP " | ||||
|  | ||||
| @CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ | ||||
|  | ||||
|   ;Remove files we installed. | ||||
|   ;Keep the list of directories here in sync with the File commands above. | ||||
| @CPACK_NSIS_DELETE_FILES@ | ||||
| @CPACK_NSIS_DELETE_DIRECTORIES@ | ||||
|  | ||||
| !ifdef CPACK_NSIS_ADD_REMOVE | ||||
|   ;Remove the add/remove program | ||||
|   Delete "$INSTDIR\AddRemove.exe" | ||||
| !endif | ||||
|  | ||||
|   ;Remove the uninstaller itself. | ||||
|   Delete "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" | ||||
|   DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" | ||||
|  | ||||
|   ;Remove the installation directory if it is empty. | ||||
|   RMDir "$INSTDIR" | ||||
|  | ||||
|   ; Remove the registry entries. | ||||
|   DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" | ||||
|  | ||||
|   ; Removes all optional components | ||||
|   !insertmacro SectionList "RemoveSection_CPack" | ||||
|  | ||||
|   !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP | ||||
|  | ||||
|   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" | ||||
| @CPACK_NSIS_DELETE_ICONS@ | ||||
| @CPACK_NSIS_DELETE_ICONS_EXTRA@ | ||||
|  | ||||
|   ;Delete empty start menu parent directories | ||||
|   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" | ||||
|  | ||||
|   startMenuDeleteLoop: | ||||
|     ClearErrors | ||||
|     RMDir $MUI_TEMP | ||||
|     GetFullPathName $MUI_TEMP "$MUI_TEMP\.." | ||||
|  | ||||
|     IfErrors startMenuDeleteLoopDone | ||||
|  | ||||
|     StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop | ||||
|   startMenuDeleteLoopDone: | ||||
|  | ||||
|   ; If the user changed the shortcut, then untinstall may not work. This should | ||||
|   ; try to fix it. | ||||
|   StrCpy $MUI_TEMP "$START_MENU" | ||||
|   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" | ||||
| @CPACK_NSIS_DELETE_ICONS_EXTRA@ | ||||
|  | ||||
|   ;Delete empty start menu parent directories | ||||
|   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" | ||||
|  | ||||
|   secondStartMenuDeleteLoop: | ||||
|     ClearErrors | ||||
|     RMDir $MUI_TEMP | ||||
|     GetFullPathName $MUI_TEMP "$MUI_TEMP\.." | ||||
|  | ||||
|     IfErrors secondStartMenuDeleteLoopDone | ||||
|  | ||||
|     StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop | ||||
|   secondStartMenuDeleteLoopDone: | ||||
|  | ||||
|   DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" | ||||
|  | ||||
|   Push $INSTDIR\bin | ||||
|   StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0 | ||||
|     Call un.RemoveFromPath | ||||
|   doNotRemoveFromPath: | ||||
| SectionEnd | ||||
|  | ||||
| ;-------------------------------- | ||||
| ; determine admin versus local install | ||||
| ; Is install for "AllUsers" or "JustMe"? | ||||
| ; Default to "JustMe" - set to "AllUsers" if admin or on Win9x | ||||
| ; This function is used for the very first "custom page" of the installer. | ||||
| ; This custom page does not show up visibly, but it executes prior to the | ||||
| ; first visible page and sets up $INSTDIR properly... | ||||
| ; Choose different default installation folder based on SV_ALLUSERS... | ||||
| ; "Program Files" for AllUsers, "My Documents" for JustMe... | ||||
|  | ||||
| Function .onInit | ||||
|   StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst | ||||
|  | ||||
|   ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString" | ||||
|   StrCmp $0 "" inst | ||||
|  | ||||
|   MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \ | ||||
|   "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \ | ||||
|   /SD IDYES IDYES uninst IDNO inst | ||||
|   Abort | ||||
|  | ||||
| ;Run the uninstaller | ||||
| uninst: | ||||
|   ClearErrors | ||||
|   StrLen $2 "\Uninstall.exe" | ||||
|   StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path | ||||
|   ExecWait '"$0" /S _?=$3' ;Do not copy the uninstaller to a temp file | ||||
|  | ||||
|   IfErrors uninst_failed inst | ||||
| uninst_failed: | ||||
|   MessageBox MB_OK|MB_ICONSTOP "Uninstall failed." | ||||
|   Abort | ||||
|  | ||||
|  | ||||
| inst: | ||||
|   ; Reads components status for registry | ||||
|   !insertmacro SectionList "InitSection" | ||||
|  | ||||
|   ; check to see if /D has been used to change | ||||
|   ; the install directory by comparing it to the | ||||
|   ; install directory that is expected to be the | ||||
|   ; default | ||||
|   StrCpy $IS_DEFAULT_INSTALLDIR 0 | ||||
|   StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2 | ||||
|     StrCpy $IS_DEFAULT_INSTALLDIR 1 | ||||
|  | ||||
|   StrCpy $SV_ALLUSERS "JustMe" | ||||
|   ; if default install dir then change the default | ||||
|   ; if it is installed for JustMe | ||||
|   StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 | ||||
|     StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@" | ||||
|  | ||||
|   ClearErrors | ||||
|   UserInfo::GetName | ||||
|   IfErrors noLM | ||||
|   Pop $0 | ||||
|   UserInfo::GetAccountType | ||||
|   Pop $1 | ||||
|   StrCmp $1 "Admin" 0 +4 | ||||
|     SetShellVarContext all | ||||
|     ;MessageBox MB_OK 'User "$0" is in the Admin group' | ||||
|     StrCpy $SV_ALLUSERS "AllUsers" | ||||
|     Goto done | ||||
|   StrCmp $1 "Power" 0 +4 | ||||
|     SetShellVarContext all | ||||
|     ;MessageBox MB_OK 'User "$0" is in the Power Users group' | ||||
|     StrCpy $SV_ALLUSERS "AllUsers" | ||||
|     Goto done | ||||
|  | ||||
|   noLM: | ||||
|     StrCpy $SV_ALLUSERS "AllUsers" | ||||
|     ;Get installation folder from registry if available | ||||
|  | ||||
|   done: | ||||
|   StrCmp $SV_ALLUSERS "AllUsers" 0 +3 | ||||
|     StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 | ||||
|       StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" | ||||
|  | ||||
|   StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 noOptionsPage | ||||
|     !insertmacro MUI_INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini" | ||||
|  | ||||
|   noOptionsPage: | ||||
| FunctionEnd | ||||
| @@ -6,7 +6,7 @@ IF (APPLE) | ||||
| ELSEIF (UNIX) | ||||
| 	SET ( CPACK_GENERATOR "TGZ") | ||||
| ELSEIF (WIN32) | ||||
| 	SET ( CPACK_GENERATOR "ZIP") | ||||
| 	SET ( CPACK_GENERATOR "ZIP" "NSIS") | ||||
| ENDIF() | ||||
|  | ||||
| # Determine packages by found generator executables | ||||
| @@ -21,32 +21,42 @@ IF(DEB_BUILDER_FOUND) | ||||
| 	SET ( CPACK_GENERATOR ${CPACK_GENERATOR} "DEB") | ||||
| ENDIF() | ||||
|  | ||||
| # Overwrite CPACK_SYSTEM_NAME for mac (visual) | ||||
| if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | ||||
|     if(${CMAKE_HOST_APPLE}) | ||||
|         set(CMAKE_SYSTEM_NAME "macOS") | ||||
|     endif() | ||||
| endif() | ||||
|  | ||||
| # Apply to all packages, some of these can be overwritten with generator specific content | ||||
| # https://cmake.org/cmake/help/v3.5/module/CPack.html | ||||
|  | ||||
| SET ( CPACK_PACKAGE_NAME "Hyperion" ) | ||||
| SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hyperion is an open source ambient light implementation" ) | ||||
| SET ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" ) | ||||
|  | ||||
| IF ( NOT DEFINED DOCKER_PLATFORM ) | ||||
| 	SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_VERSION}-${CMAKE_SYSTEM_NAME}") | ||||
| ELSE() | ||||
| 	SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_VERSION}-${CMAKE_SYSTEM_NAME}-${DOCKER_PLATFORM}") | ||||
| ENDIF() | ||||
| SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") | ||||
|  | ||||
| SET ( CPACK_PACKAGE_CONTACT "packages@hyperion-project.org") | ||||
| SET ( CPACK_PACKAGE_VENDOR "hyperion-project") | ||||
| SET ( CPACK_PACKAGE_EXECUTABLES "hyperiond;Hyperion" ) | ||||
| SET ( CPACK_PACKAGE_INSTALL_DIRECTORY "Hyperion" ) | ||||
| SET ( CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources/icons/hyperion-icon-32px.png") | ||||
|  | ||||
| SET ( CPACK_PACKAGE_VERSION_MAJOR "${HYPERION_VERSION_MAJOR}") | ||||
| SET ( CPACK_PACKAGE_VERSION_MINOR "${HYPERION_VERSION_MINOR}") | ||||
| SET ( CPACK_PACKAGE_VERSION_PATCH "${HYPERION_VERSION_PATCH}") | ||||
| SET ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" ) | ||||
| SET ( CPACK_PACKAGE_EXECUTABLES "hyperiond;Hyperion" ) | ||||
| SET ( CPACK_CREATE_DESKTOP_LINKS "hyperiond;Hyperion" ) | ||||
|  | ||||
| # Define the install prefix path for cpack | ||||
| IF ( UNIX ) | ||||
| 	#SET ( CPACK_PACKAGING_INSTALL_PREFIX "share/hyperion") | ||||
| ENDIF() | ||||
|  | ||||
| # Specific CPack Package Generators | ||||
| # https://cmake.org/Wiki/CMake:CPackPackageGenerators | ||||
| # .deb files for apt | ||||
|  | ||||
| SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/preinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/prerm" ) | ||||
| SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" ) | ||||
|  | ||||
| @@ -55,8 +65,6 @@ SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" ) | ||||
| SET ( CPACK_RPM_PACKAGE_RELEASE 1) | ||||
| SET ( CPACK_RPM_PACKAGE_LICENSE "MIT") | ||||
| SET ( CPACK_RPM_PACKAGE_GROUP "Applications") | ||||
|  | ||||
| # Notes: This is a dependency list for Fedora 27, different .rpm OSes use different names for their deps | ||||
| SET ( CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/preinst" ) | ||||
| SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/postinst" ) | ||||
| SET ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/prerm" ) | ||||
| @@ -68,29 +76,162 @@ SET ( CPACK_BUNDLE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/cmake/osxbundle/Hyperion.icn | ||||
| SET ( CPACK_BUNDLE_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/cmake/osxbundle/Info.plist ) | ||||
| SET ( CPACK_BUNDLE_STARTUP_COMMAND "${CMAKE_SOURCE_DIR}/cmake/osxbundle/launch.sh" ) | ||||
|  | ||||
| # NSIS for windows, requires NSIS TODO finish | ||||
| SET ( CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/installer.ico") | ||||
| SET ( CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/uninstaller.ico") | ||||
| #SET ( CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/installer.bmp") #bmp required? If so, wrap in WIN32 check else: Use default icon instead | ||||
| SET ( CPACK_NSIS_MODIFY_PATH ON) | ||||
| SET ( CPACK_NSIS_DISPLAY_NAME "Hyperion Installer") | ||||
| SET ( CPACK_NSIS_INSTALLED_ICON_NAME "Link to .exe") | ||||
| # Windows NSIS | ||||
| # Use custom script based on cpack nsis template | ||||
| set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/nsis/template ${CMAKE_MODULE_PATH}) | ||||
| # Some path transformations | ||||
| if(WIN32) | ||||
| 	file(TO_NATIVE_PATH ${CPACK_PACKAGE_ICON} CPACK_PACKAGE_ICON) | ||||
| 	STRING(REGEX REPLACE "\\\\" "\\\\\\\\" CPACK_PACKAGE_ICON ${CPACK_PACKAGE_ICON}) | ||||
| endif() | ||||
| file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/installer.ico" NSIS_HYP_ICO) | ||||
| file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/hyperion-logo.bmp" NSIS_HYP_LOGO_HORI) | ||||
| file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/hyperion-logo-vert.bmp" NSIS_HYP_LOGO_VERT) | ||||
| STRING(REGEX REPLACE "\\\\" "\\\\\\\\" NSIS_HYP_ICO "${NSIS_HYP_ICO}") | ||||
| STRING(REGEX REPLACE "\\\\" "\\\\\\\\" NSIS_HYP_LOGO_VERT "${NSIS_HYP_LOGO_VERT}") | ||||
| STRING(REGEX REPLACE "\\\\" "\\\\\\\\" NSIS_HYP_LOGO_HORI "${NSIS_HYP_LOGO_HORI}") | ||||
|  | ||||
| SET ( CPACK_NSIS_MODIFY_PATH ON ) | ||||
| SET ( CPACK_NSIS_MUI_ICON ${NSIS_HYP_ICO}) | ||||
| SET ( CPACK_NSIS_MUI_UNIICON ${NSIS_HYP_ICO}) | ||||
| SET ( CPACK_NSIS_MUI_HEADERIMAGE ${NSIS_HYP_LOGO_HORI} ) | ||||
| SET ( CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP ${NSIS_HYP_LOGO_VERT}) | ||||
| SET ( CPACK_NSIS_DISPLAY_NAME "Hyperion Ambient Light") | ||||
| SET ( CPACK_NSIS_PACKAGE_NAME "Hyperion" ) | ||||
| SET ( CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\hyperiond.exe") | ||||
| SET ( CPACK_NSIS_HELP_LINK "https://www.hyperion-project.org") | ||||
| SET ( CPACK_NSIS_URL_INFO_ABOUT "https://www.hyperion-project.org") | ||||
| # hyperiond startmenu link | ||||
| #SET ( CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Hyperion.lnk' '$INSTDIR\\\\bin\\\\hyperiond.exe'") | ||||
| #SET ( CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\Hyperion.lnk'") | ||||
| # hyperiond desktop link | ||||
| #SET ( CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$DESKTOP\\\\Hyperion.lnk' '$INSTDIR\\\\bin\\\\hyperiond.exe' ") | ||||
| #SET ( CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "Delete '$DESKTOP\\\\Hyperion.lnk' ") | ||||
|  | ||||
| # With cli args: SET ( CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Hyperion (Debug).lnk' '$INSTDIR\\\\bin\\\\hyperiond.exe' '-d'") | ||||
| #SET ( CPACK_NSIS_EXTRA_INSTALL_COMMANDS "CreateShortCut \\\"$DESKTOP\\\\Hyperion.lnk\\\" \\\"$INSTDIR\\\\bin\\\\hyperiond.exe\\\" ") | ||||
| #SET ( CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "Delete \\\"$DESKTOP\\\\Hyperion.lnk\\\" ") | ||||
|  | ||||
| # define the install components | ||||
| SET ( CPACK_COMPONENTS_ALL "${PLATFORM}" ) | ||||
| # See also https://gitlab.kitware.com/cmake/community/-/wikis/doc/cpack/Component-Install-With-CPack | ||||
| # and https://cmake.org/cmake/help/latest/module/CPackComponent.html | ||||
| SET ( CPACK_COMPONENTS_GROUPING "ALL_COMPONENTS_IN_ONE") | ||||
| # Components base | ||||
| SET ( CPACK_COMPONENTS_ALL "Hyperion" "hyperion_remote" ) | ||||
| # optional compiled | ||||
| if(ENABLE_QT) | ||||
| 	SET ( CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} "hyperion_qt" ) | ||||
| endif() | ||||
| if(ENABLE_AMLOGIC) | ||||
| 	SET ( CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} "hyperion_aml" ) | ||||
| endif() | ||||
| if(ENABLE_V4L2) | ||||
| 	SET ( CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} "hyperion_v4l2" ) | ||||
| endif() | ||||
| if(ENABLE_X11) | ||||
| 	SET ( CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} "hyperion_x11" ) | ||||
| endif() | ||||
| if(ENABLE_DISPMANX) | ||||
| 	SET ( CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} "hyperion_dispmanx" ) | ||||
| endif() | ||||
| if(ENABLE_FB) | ||||
| 	SET ( CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} "hyperion_framebuffer" ) | ||||
| endif() | ||||
| if(ENABLE_OSX) | ||||
| 	SET ( CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} "hyperion_osx" ) | ||||
| endif() | ||||
|  | ||||
| SET ( CPACK_COMPONENT_${PLATFORM}_ARCHIVE_FILE "${CPACK_PACKAGE_FILE_NAME}" ) | ||||
| SET ( CPACK_ARCHIVE_COMPONENT_INSTALL ON ) | ||||
|  | ||||
| SET ( CPACK_DEBIAN_${PLATFORM}_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.deb" ) | ||||
| SET ( CPACK_DEB_COMPONENT_INSTALL ON ) | ||||
|  | ||||
| SET ( CPACK_RPM_${PLATFORM}_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.rpm" ) | ||||
| SET ( CPACK_RPM_COMPONENT_INSTALL ON ) | ||||
|  | ||||
| SET ( CPACK_STRIP_FILES ON ) | ||||
|  | ||||
| # no code after following line! | ||||
| INCLUDE ( CPack ) | ||||
|  | ||||
| cpack_add_install_type(Full DISPLAY_NAME "Full") | ||||
| cpack_add_install_type(Min DISPLAY_NAME "Minimal") | ||||
| cpack_add_component_group(Runtime EXPANDED DESCRIPTION "Hyperion runtime and hyperion-remote commandline tool") | ||||
| cpack_add_component_group(Screencapture EXPANDED DESCRIPTION "Standalone Screencapture commandline programs") | ||||
| # Components base | ||||
| cpack_add_component(Hyperion | ||||
| 	DISPLAY_NAME "Hyperion" | ||||
| 	DESCRIPTION "Hyperion runtime" | ||||
| 	INSTALL_TYPES Full Min | ||||
| 	GROUP Runtime | ||||
| 	REQUIRED | ||||
| ) | ||||
| cpack_add_component(hyperion_remote | ||||
| 	DISPLAY_NAME "Hyperion Remote" | ||||
| 	DESCRIPTION "Hyperion remote cli tool" | ||||
| 	INSTALL_TYPES Full | ||||
| 	GROUP Runtime | ||||
| 	DEPENDS Hyperion | ||||
| ) | ||||
|  | ||||
| # optional compiled | ||||
| if(ENABLE_QT) | ||||
| 	cpack_add_component(hyperion_qt | ||||
| 		DISPLAY_NAME "Qt Standalone Screencap" | ||||
| 		DESCRIPTION "Qt based standalone screen capture" | ||||
| 		INSTALL_TYPES Full | ||||
| 		GROUP Screencapture | ||||
| 		DEPENDS Hyperion | ||||
| 	) | ||||
| endif() | ||||
| if(ENABLE_AMLOGIC) | ||||
| 	cpack_add_component(hyperion_aml | ||||
| 		DISPLAY_NAME "Amlogic Standalone Screencap" | ||||
| 		DESCRIPTION "Amlogic based standalone screen capture" | ||||
| 		INSTALL_TYPES Full | ||||
| 		GROUP Screencapture | ||||
| 		DEPENDS Hyperion | ||||
| 	) | ||||
| endif() | ||||
| if(ENABLE_V4L2) | ||||
| 	cpack_add_component(hyperion_v4l2 | ||||
| 		DISPLAY_NAME "V4l2 Standalone Screencap" | ||||
| 		DESCRIPTION "Video for Linux 2 based standalone screen capture" | ||||
| 		INSTALL_TYPES Full | ||||
| 		GROUP Screencapture | ||||
| 		DEPENDS Hyperion | ||||
| 	) | ||||
| endif() | ||||
| if(ENABLE_X11) | ||||
| 	cpack_add_component(hyperion_x11 | ||||
| 		DISPLAY_NAME "X11 Standalone Screencap" | ||||
| 		DESCRIPTION "X11 based standalone screen capture" | ||||
| 		INSTALL_TYPES Full | ||||
| 		GROUP Screencapture | ||||
| 		DEPENDS Hyperion | ||||
| 	) | ||||
| endif() | ||||
| if(ENABLE_DISPMANX) | ||||
| 	cpack_add_component(hyperion_dispmanx | ||||
| 		DISPLAY_NAME "RPi dispmanx Standalone Screencap" | ||||
| 		DESCRIPTION "Raspbery Pi dispmanx based standalone screen capture" | ||||
| 		INSTALL_TYPES Full | ||||
| 		GROUP Screencapture | ||||
| 		DEPENDS Hyperion | ||||
| 	) | ||||
| endif() | ||||
| if(ENABLE_FB) | ||||
| 	cpack_add_component(hyperion_framebuffer | ||||
| 		DISPLAY_NAME "Framebuffer Standalone Screencap" | ||||
| 		DESCRIPTION "Framebuffer based standalone screen capture" | ||||
| 		INSTALL_TYPES Full | ||||
| 		GROUP Screencapture | ||||
| 		DEPENDS Hyperion | ||||
| 	) | ||||
| endif() | ||||
| if(ENABLE_OSX) | ||||
| 	cpack_add_component(hyperion_osx | ||||
| 		DISPLAY_NAME "Mac osx Standalone Screencap" | ||||
| 		DESCRIPTION "Mac osx based standalone screen capture" | ||||
| 		INSTALL_TYPES Full | ||||
| 		GROUP Screencapture | ||||
| 		DEPENDS Hyperion | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
|   | ||||
							
								
								
									
										8
									
								
								dependencies/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								dependencies/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,8 @@ | ||||
| add_subdirectory(build/hidapi) | ||||
| add_subdirectory(build/tinkerforge) | ||||
|  | ||||
| if ( ENABLE_TINKERFORGE ) | ||||
| 	add_subdirectory(build/tinkerforge) | ||||
| endif() | ||||
|  | ||||
| if(ENABLE_WS281XPWM) | ||||
| 	add_library(ws281x | ||||
| @@ -58,6 +61,7 @@ message(STATUS "Using flatbuffers compiler: " ${FLATBUFFERS_FLATC_EXECUTABLE}) | ||||
|  | ||||
| function(compile_flattbuffer_schema SRC_FBS OUTPUT_DIR) | ||||
| 	string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS}) | ||||
| 	set_property(SOURCE ${GEN_HEADER} PROPERTY SKIP_AUTOMOC ON) | ||||
| 	if (ENABLE_AMLOGIC) | ||||
| 		add_custom_command( | ||||
| 			OUTPUT ${GEN_HEADER} | ||||
| @@ -181,6 +185,8 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS) | ||||
| 			COMMENT "Running C++ protocol buffer compiler on ${FIL}" | ||||
| 			VERBATIM | ||||
| 		) | ||||
| 		set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc" PROPERTY SKIP_AUTOMOC ON) | ||||
| 		set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h" PROPERTY SKIP_AUTOMOC ON) | ||||
| 	endforeach() | ||||
|  | ||||
| 	set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) | ||||
|   | ||||
| @@ -1,18 +1,17 @@ | ||||
| # Install Hyperion | ||||
| Hyperion supports various platforms for installation, as package or as a portable .zip. | ||||
| Hyperion supports various platforms for installation, as package or portable .zip. | ||||
|  | ||||
| ## Requirements | ||||
|  | ||||
| ### Supported Hardware/Software | ||||
| ### Supported Systems | ||||
|   * Raspberry Pi (See also [HyperBian](/en/user/HyperBian)) | ||||
|   * Debian 9 | Ubuntu 16.04 or higher | ||||
|   * Mac OS | ||||
|   * OpenELEC, LibreELEC | ||||
|  | ||||
| **Please note that some arm devices have limited support in terms of direct capturing** | ||||
| **Please note that some arm devices have limited support in terms of screen capturing** | ||||
|  | ||||
| ### Supported Browsers | ||||
| Hyperion will be configured and controlled trough a web configuration. Also for mobile browsers. | ||||
| Hyperion will be configured and controlled trough a web interface. | ||||
|   * Chrome 47+ | ||||
|   * Firefox 43+ | ||||
|   * Opera 34+ | ||||
| @@ -20,32 +19,31 @@ Hyperion will be configured and controlled trough a web configuration. Also for | ||||
|   * Microsoft Edge 14+ | ||||
|  | ||||
| ::: warning Internet Explorer | ||||
| Intenet Explorer is not supported | ||||
| Internet Explorer is not supported | ||||
| ::: | ||||
|  | ||||
| ## Install Hyperion | ||||
|   * Raspberry Pi you can use [HyperBian](/en/user/HyperBian.md) for a fresh start. Or use the install system | ||||
|   * We provide installation packages (.deb) to install Hyperion with a single click on Debian/Ubuntu based systems. | ||||
|   * A script installation for read-only systems like OpenELEC, LibreELEC. | ||||
|   * Mac OSX - currently just a zip file with the binary | ||||
|  | ||||
| ### Debian/Ubuntu | ||||
| For Debian/Ubuntu we provide a .deb file. A one click installation package that does the job for you. \ | ||||
| Download the file here: \ | ||||
| Download the file from the [Release page](https://github.com/hyperion-project/hyperion.ng/releases) \ | ||||
| Install from commandline by typing. \ | ||||
| `sudo apt install ./Hyperion-2.0.0-Linux-x86_64-x11.deb` \ | ||||
| `sudo apt install ./Hyperion-2.0.0-Linux-x86_64.deb` \ | ||||
| Hyperion can be now started from your start menu. | ||||
|  | ||||
| ### Fedora | ||||
| For Fedora we provide a .rpm file. A one click installation package that does the job for you. \ | ||||
| Download the file here: \ | ||||
| Download the file from the [Release page](https://github.com/hyperion-project/hyperion.ng/releases) \ | ||||
| Install from commandline by typing. \ | ||||
| `sudo dnf install ./Hyperion-2.0.0-Linux-x86_64-x11.rpm` \ | ||||
| `sudo dnf install ./Hyperion-2.0.0-Linux-x86_64.rpm` \ | ||||
| Hyperion can be now started from your start menu. | ||||
|  | ||||
| ## Uninstall Hyperion | ||||
| On Debian/Ubuntu you can remove Hyperion with this command \ | ||||
| `sudo apt remove hyperion*` \ | ||||
| `sudo apt remove hyperion` \ | ||||
|  | ||||
| ### Hyperion user data | ||||
| Hyperion stores user data inside your home directory (folder `.hyperion`). | ||||
| Hyperion stores user data inside your home directory (folder `.hyperion`). | ||||
|   | ||||
| @@ -7,7 +7,9 @@ | ||||
| // components def | ||||
| #include <utils/Components.h> | ||||
| // bonjour | ||||
| #ifdef ENABLE_AVAHI | ||||
| #include <bonjour/bonjourrecord.h> | ||||
| #endif | ||||
| // videModes | ||||
| #include <utils/VideoMode.h> | ||||
| // settings | ||||
| @@ -69,13 +71,13 @@ private slots: | ||||
| 	/// @brief handle component state changes | ||||
| 	/// | ||||
| 	void handleComponentState(const hyperion::Components comp, const bool state); | ||||
|  | ||||
| #ifdef ENABLE_AVAHI | ||||
| 	/// | ||||
| 	/// @brief handle emits from bonjour wrapper | ||||
| 	/// @param  bRegisters   The full register map | ||||
| 	/// | ||||
| 	void handleBonjourChange(const QMap<QString,BonjourRecord>& bRegisters); | ||||
|  | ||||
| #endif | ||||
| 	/// | ||||
| 	/// @brief handle emits from PriorityMuxer | ||||
| 	/// | ||||
| @@ -131,8 +133,10 @@ private: | ||||
| 	Hyperion* _hyperion; | ||||
| 	/// pointer of comp register | ||||
| 	ComponentRegister* _componentRegister; | ||||
| #ifdef ENABLE_AVAHI | ||||
| 	/// Bonjour instance | ||||
| 	BonjourBrowserWrapper* _bonjour; | ||||
| #endif | ||||
| 	/// priority muxer instance | ||||
| 	PriorityMuxer* _prioMuxer; | ||||
| 	/// contains all available commands | ||||
|   | ||||
| @@ -8,6 +8,11 @@ | ||||
| #include <cassert> | ||||
| #include <utils/ColorRgb.h> | ||||
|  | ||||
| // https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types#ssize-t | ||||
| #if defined(_MSC_VER) | ||||
| #include <BaseTsd.h> | ||||
| typedef SSIZE_T ssize_t; | ||||
| #endif | ||||
|  | ||||
| template <typename Pixel_T> | ||||
| class Image | ||||
|   | ||||
| @@ -16,13 +16,13 @@ | ||||
| #define Debug(logger, ...)   (logger)->Message(Logger::DEBUG  , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define Info(logger, ...)    (logger)->Message(Logger::INFO   , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define Warning(logger, ...) (logger)->Message(Logger::WARNING, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define Error(logger, ...)   (logger)->Message(Logger::ERROR  , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define Error(logger, ...)   (logger)->Message(Logger::ERRORR  , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
|  | ||||
| // conditional log messages | ||||
| #define DebugIf(condition, logger, ...)   if (condition) (logger)->Message(Logger::DEBUG   , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define InfoIf(condition, logger, ...)    if (condition) (logger)->Message(Logger::INFO    , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define WarningIf(condition, logger, ...) if (condition) (logger)->Message(Logger::WARNING , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define ErrorIf(condition, logger, ...)   if (condition) (logger)->Message(Logger::ERROR   , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
| #define ErrorIf(condition, logger, ...)   if (condition) (logger)->Message(Logger::ERRORR   , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) | ||||
|  | ||||
| // ================================================================ | ||||
|  | ||||
| @@ -31,7 +31,14 @@ class Logger : public QObject | ||||
| 	Q_OBJECT | ||||
|  | ||||
| public: | ||||
| 	enum LogLevel { UNSET=0,DEBUG=1, INFO=2,WARNING=3,ERROR=4,OFF=5 }; | ||||
| 	enum LogLevel { | ||||
| 		UNSET, | ||||
| 		DEBUG, | ||||
| 		INFO, | ||||
| 		WARNING, | ||||
| 		ERRORR, | ||||
| 		OFF | ||||
| 	}; | ||||
|  | ||||
| 	typedef struct | ||||
| 	{ | ||||
|   | ||||
| @@ -2,7 +2,6 @@ | ||||
|  | ||||
| #include <QObject> | ||||
| #include <QString> | ||||
| #include <QByteArray> | ||||
|  | ||||
| class SysInfo : public QObject | ||||
| { | ||||
| @@ -30,27 +29,4 @@ private: | ||||
| 	static SysInfo* _instance; | ||||
|  | ||||
| 	HyperionSysInfo _sysinfo; | ||||
|  | ||||
| 	struct QUnixOSVersion | ||||
| 	{ | ||||
| 		QString productType; | ||||
| 		QString productVersion; | ||||
| 		QString prettyName; | ||||
| 	}; | ||||
|  | ||||
| 	QString machineHostName(); | ||||
| 	QString currentCpuArchitecture(); | ||||
| 	QString kernelType(); | ||||
| 	QString kernelVersion(); | ||||
| 	bool findUnixOsVersion(QUnixOSVersion &v); | ||||
|  | ||||
| 	QByteArray getEtcFileFirstLine(const char *fileName); | ||||
| 	bool readEtcRedHatRelease(QUnixOSVersion &v); | ||||
| 	bool readEtcDebianVersion(QUnixOSVersion &v); | ||||
|  | ||||
| 	bool readEtcOsRelease(SysInfo::QUnixOSVersion &v); | ||||
| 	bool readEtcFile(SysInfo::QUnixOSVersion &v, const char *filename, const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey); | ||||
| 	QByteArray getEtcFileContent(const char *filename); | ||||
| 	QString unquote(const char *begin, const char *end); | ||||
| 	bool readEtcLsbRelease(SysInfo::QUnixOSVersion &v); | ||||
| }; | ||||
|   | ||||
| @@ -9,7 +9,6 @@ add_subdirectory(blackborder) | ||||
| add_subdirectory(jsonserver) | ||||
| add_subdirectory(flatbufserver) | ||||
| add_subdirectory(protoserver) | ||||
| add_subdirectory(bonjour) | ||||
| add_subdirectory(ssdp) | ||||
| add_subdirectory(boblightserver) | ||||
| add_subdirectory(leddevice) | ||||
| @@ -20,3 +19,7 @@ add_subdirectory(webserver) | ||||
| add_subdirectory(db) | ||||
| add_subdirectory(api) | ||||
| add_subdirectory(python) | ||||
|  | ||||
| if(ENABLE_AVAHI) | ||||
|   add_subdirectory(bonjour) | ||||
| endif() | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include <QBuffer> | ||||
| #include <QByteArray> | ||||
| #include <QTimer> | ||||
| #include <QHostInfo> | ||||
|  | ||||
| // hyperion includes | ||||
| #include <leddevice/LedDeviceWrapper.h> | ||||
| @@ -26,7 +27,9 @@ | ||||
| #include <utils/JsonUtils.h> | ||||
|  | ||||
| // bonjour wrapper | ||||
| #ifdef ENABLE_AVAHI | ||||
| #include <bonjour/bonjourbrowserwrapper.h> | ||||
| #endif | ||||
|  | ||||
| // ledmapping int <> string transform methods | ||||
| #include <hyperion/ImageProcessor.h> | ||||
| @@ -469,9 +472,8 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString | ||||
|  | ||||
| 	QJsonObject grabbers; | ||||
| 	QJsonArray availableGrabbers; | ||||
| 	QJsonObject availableProperties; | ||||
|  | ||||
| #if defined(ENABLE_DISPMANX) || defined(ENABLE_V4L2) || defined(ENABLE_FB) || defined(ENABLE_AMLOGIC) || defined(ENABLE_OSX) || defined(ENABLE_X11) | ||||
| #if defined(ENABLE_DISPMANX) || defined(ENABLE_V4L2) || defined(ENABLE_FB) || defined(ENABLE_AMLOGIC) || defined(ENABLE_OSX) || defined(ENABLE_X11) || defined(ENABLE_QT) | ||||
|  | ||||
| 	// get available grabbers | ||||
| 	//grabbers["active"] = ????; | ||||
| @@ -535,7 +537,8 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString | ||||
|  | ||||
| 	// add sessions | ||||
| 	QJsonArray sessions; | ||||
| 	for (auto session : BonjourBrowserWrapper::getInstance()->getAllServices()) | ||||
| #ifdef ENABLE_AVAHI | ||||
| 	for (auto session: BonjourBrowserWrapper::getInstance()->getAllServices()) | ||||
| 	{ | ||||
| 		if (session.port < 0) | ||||
| 			continue; | ||||
| @@ -549,7 +552,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString | ||||
| 		sessions.append(item); | ||||
| 	} | ||||
| 	info["sessions"] = sessions; | ||||
|  | ||||
| #endif | ||||
| 	// add instance info | ||||
| 	QJsonArray instanceInfo; | ||||
| 	for (const auto &entry : API::getAllInstanceData()) | ||||
|   | ||||
| @@ -10,8 +10,9 @@ | ||||
|  | ||||
| #include <hyperion/ComponentRegister.h> | ||||
| // bonjour wrapper | ||||
|  | ||||
| #ifdef ENABLE_AVAHI | ||||
| #include <bonjour/bonjourbrowserwrapper.h> | ||||
| #endif | ||||
| // priorityMuxer | ||||
|  | ||||
| #include <hyperion/PriorityMuxer.h> | ||||
| @@ -21,6 +22,7 @@ | ||||
|  | ||||
| // qt | ||||
| #include <QDateTime> | ||||
| #include <QVariant> | ||||
|  | ||||
| // Image to led map helper | ||||
| #include <hyperion/ImageProcessor.h> | ||||
| @@ -31,7 +33,9 @@ JsonCB::JsonCB(QObject* parent) | ||||
| 	: QObject(parent) | ||||
| 	, _hyperion(nullptr) | ||||
| 	, _componentRegister(nullptr) | ||||
| 	#ifdef ENABLE_AVAHI | ||||
| 	, _bonjour(BonjourBrowserWrapper::getInstance()) | ||||
| 	#endif | ||||
| 	, _prioMuxer(nullptr) | ||||
| { | ||||
| 	_availableCommands << "components-update" << "sessions-update" << "priorities-update" << "imageToLedMapping-update" | ||||
| @@ -58,10 +62,12 @@ bool JsonCB::subscribeFor(const QString& type, const bool & unsubscribe) | ||||
|  | ||||
| 	if(type == "sessions-update") | ||||
| 	{ | ||||
| #ifdef ENABLE_AVAHI | ||||
| 		if(unsubscribe) | ||||
| 			disconnect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange); | ||||
| 		else | ||||
| 			connect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange, Qt::UniqueConnection); | ||||
| #endif | ||||
| 	} | ||||
|  | ||||
| 	if(type == "priorities-update") | ||||
| @@ -188,7 +194,7 @@ void JsonCB::handleComponentState(const hyperion::Components comp, const bool st | ||||
|  | ||||
| 	doCallback("components-update", QVariant(data)); | ||||
| } | ||||
|  | ||||
| #ifdef ENABLE_AVAHI | ||||
| void JsonCB::handleBonjourChange(const QMap<QString,BonjourRecord>& bRegisters) | ||||
| { | ||||
| 	QJsonArray data; | ||||
| @@ -207,7 +213,7 @@ void JsonCB::handleBonjourChange(const QMap<QString,BonjourRecord>& bRegisters) | ||||
|  | ||||
| 	doCallback("sessions-update", QVariant(data)); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| void JsonCB::handlePriorityUpdate() | ||||
| { | ||||
| 	QJsonObject data; | ||||
|   | ||||
| @@ -1,9 +1,16 @@ | ||||
| set(Python_ADDITIONAL_VERSIONS 3.5) | ||||
| find_package(PythonLibs 3.5 REQUIRED) | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	find_package(Python3 COMPONENTS Interpreter Development REQUIRED) | ||||
| else() | ||||
| 	find_package (PythonLibs ${PYTHON_VERSION_STRING} EXACT) # Maps PythonLibs to the PythonInterp version of the main cmake | ||||
| endif() | ||||
|  | ||||
| # Include the python directory. Also include the parent (which is for example /usr/include) | ||||
| # which may be required when it is not includes by the (cross-) compiler by default. | ||||
| include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	include_directories(${Python3_INCLUDE_DIRS} ${Python3_INCLUDE_DIRS}/..) | ||||
| else() | ||||
| 	include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | ||||
| endif() | ||||
|  | ||||
| # Define the current source locations | ||||
| SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/effectengine) | ||||
| @@ -31,5 +38,10 @@ target_link_libraries(effectengine | ||||
| 	python | ||||
| 	Qt5::Core | ||||
| 	Qt5::Gui | ||||
| 	${PYTHON_LIBRARIES} | ||||
| ) | ||||
|  | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	target_link_libraries( effectengine ${Python3_LIBRARIES} ) | ||||
| else() | ||||
| 	target_link_libraries( effectengine ${PYTHON_LIBRARIES} ) | ||||
| endif() | ||||
|   | ||||
| @@ -100,8 +100,17 @@ int QtGrabber::grabFrame(Image<ColorRgb> & image) | ||||
| 	} | ||||
| 	QPixmap originalPixmap = _screen->grabWindow(0, _src_x, _src_y, _src_x_max, _src_y_max); | ||||
| 	QPixmap resizedPixmap = originalPixmap.scaled(_width,_height); | ||||
| 	QImage img = resizedPixmap.toImage().convertToFormat( QImage::Format_RGB888); | ||||
| 	memcpy(image.memptr(), img.bits(),(size_t) _width*_height*3); | ||||
| 	QImage imageFrame = resizedPixmap.toImage().convertToFormat( QImage::Format_RGB888); | ||||
|  | ||||
| 	for (int y=0; y<imageFrame.height(); ++y) | ||||
| 		for (int x=0; x<imageFrame.width(); ++x) | ||||
| 		{ | ||||
| 			QColor inPixel(imageFrame.pixel(x,y)); | ||||
| 			ColorRgb & outPixel = image(x,y); | ||||
| 			outPixel.red   = inPixel.red(); | ||||
| 			outPixel.green = inPixel.green(); | ||||
| 			outPixel.blue  = inPixel.blue(); | ||||
| 		} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -22,9 +22,12 @@ target_link_libraries(hyperion | ||||
| 	flatbufserver | ||||
| 	flatbuffers | ||||
| 	leddevice | ||||
| 	bonjour | ||||
| 	boblightserver | ||||
| 	effectengine | ||||
| 	database | ||||
| 	${QT_LIBRARIES} | ||||
| ) | ||||
|  | ||||
| if (ENABLE_AVAHI) | ||||
| 	target_link_libraries(hyperion bonjour) | ||||
| endif () | ||||
|   | ||||
| @@ -2,7 +2,6 @@ | ||||
| // STL includes | ||||
| #include <exception> | ||||
| #include <sstream> | ||||
| #include <unistd.h> | ||||
|  | ||||
| // QT includes | ||||
| #include <QString> | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| // STL includes | ||||
| #include <cstring> | ||||
| #include <unistd.h> | ||||
| #include <iostream> | ||||
|  | ||||
| // hyperion includes | ||||
|   | ||||
| @@ -6,7 +6,9 @@ | ||||
| #include "JsonClientConnection.h" | ||||
|  | ||||
| // bonjour include | ||||
| #ifdef ENABLE_AVAHI | ||||
| #include <bonjour/bonjourserviceregister.h> | ||||
| #endif | ||||
| #include <utils/NetOrigin.h> | ||||
|  | ||||
| // qt includes | ||||
| @@ -49,7 +51,7 @@ void JsonServer::start() | ||||
| 		return; | ||||
| 	} | ||||
| 	Info(_log, "Started on port %d", _port); | ||||
|  | ||||
| #ifdef ENABLE_AVAHI | ||||
| 	if(_serviceRegister == nullptr) | ||||
| 	{ | ||||
| 		_serviceRegister = new BonjourServiceRegister(this); | ||||
| @@ -61,6 +63,7 @@ void JsonServer::start() | ||||
| 		_serviceRegister = new BonjourServiceRegister(this); | ||||
| 		_serviceRegister->registerService("_hyperiond-json._tcp", _port); | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void JsonServer::stop() | ||||
|   | ||||
| @@ -27,7 +27,7 @@ FILE ( GLOB Leddevice_SOURCES | ||||
| 	"${CURRENT_SOURCE_DIR}/dev_other/*.cpp" | ||||
| ) | ||||
|  | ||||
| if ( ENABLE_OSX ) | ||||
| if ( ENABLE_OSX OR WIN32 ) | ||||
| 	list(REMOVE_ITEM Leddevice_SOURCES "${CURRENT_SOURCE_DIR}/dev_other/LedDevicePiBlaster.h") | ||||
| 	list(REMOVE_ITEM Leddevice_SOURCES "${CURRENT_SOURCE_DIR}/dev_other/LedDevicePiBlaster.cpp") | ||||
| endif() | ||||
| @@ -87,9 +87,13 @@ target_link_libraries(leddevice | ||||
| 	${CMAKE_THREAD_LIBS_INIT} | ||||
| 	Qt5::Network | ||||
| 	Qt5::SerialPort | ||||
|         ssdp | ||||
|   ssdp | ||||
| ) | ||||
|  | ||||
| if(WIN32) | ||||
| 	target_link_libraries(leddevice ws2_32) | ||||
| endif() | ||||
|  | ||||
| if(ENABLE_TINKERFORGE) | ||||
| 	target_link_libraries(leddevice tinkerforge) | ||||
| endif() | ||||
|   | ||||
| @@ -1,5 +1,11 @@ | ||||
| #include "LedDeviceFadeCandy.h" | ||||
|  | ||||
| // https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types#ssize-t | ||||
| #if defined(_MSC_VER) | ||||
| #include <BaseTsd.h> | ||||
| typedef SSIZE_T ssize_t; | ||||
| #endif | ||||
|  | ||||
| static const signed   MAX_NUM_LEDS    = 10000; // OPC can handle 21845 leds - in theory, fadecandy device should handle 10000 leds | ||||
| static const unsigned OPC_SET_PIXELS  = 0;     // OPC command codes | ||||
| static const unsigned OPC_SYS_EX      = 255;     // OPC command codes | ||||
|   | ||||
| @@ -1,4 +1,9 @@ | ||||
| #ifdef _WIN32 | ||||
| #include <winsock.h> | ||||
| #else | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
|  | ||||
| #include <QHostInfo> | ||||
|  | ||||
| // hyperion local includes | ||||
|   | ||||
| @@ -20,6 +20,7 @@ const ushort ARTNET_DEFAULT_PORT = 6454; | ||||
| // http://stackoverflow.com/questions/16396013/artnet-packet-structure | ||||
| typedef union | ||||
| { | ||||
| #pragma pack(push, 1) | ||||
| 	struct { | ||||
| 		char		ID[8];		// "Art-Net" | ||||
| 		uint16_t	OpCode;		// See Doc. Table 1 - OpCodes eg. 0x5000 OpOutput / OpDmx | ||||
| @@ -30,7 +31,8 @@ typedef union | ||||
| 		uint8_t		Net;		// high universe (not used) | ||||
| 		uint16_t	Length;		// data length (2 - 512) | ||||
| 		uint8_t		Data[ DMX_MAX ];	// universe data | ||||
| 	} __attribute__((packed)); | ||||
| 	}; | ||||
| #pragma pack(pop) | ||||
|  | ||||
| 	uint8_t raw[ 18 + DMX_MAX ]; | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,9 @@ | ||||
| #ifdef _WIN32 | ||||
| #include <winsock.h> | ||||
| #else | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
|  | ||||
| #include <QHostInfo> | ||||
|  | ||||
| // hyperion local includes | ||||
|   | ||||
| @@ -48,6 +48,7 @@ const ushort E131_DEFAULT_PORT = 5568; | ||||
| /* E1.31 Packet Structure */ | ||||
| typedef union | ||||
| { | ||||
| #pragma pack(push, 1) | ||||
| 	struct | ||||
| 	{ | ||||
| 		/* Root Layer */ | ||||
| @@ -76,7 +77,8 @@ typedef union | ||||
| 		uint16_t address_increment; | ||||
| 		uint16_t property_value_count; | ||||
| 		uint8_t  property_values[513]; | ||||
| 	} __attribute__((packed)); | ||||
| 	}; | ||||
| #pragma pack(pop) | ||||
|  | ||||
| 	uint8_t raw[638]; | ||||
| } e131_packet_t; | ||||
|   | ||||
| @@ -6,7 +6,6 @@ | ||||
| #include <exception> | ||||
| // Linux includes | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
|  | ||||
| #include <QStringList> | ||||
| #include <QUdpSocket> | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| #include "LedDeviceDMX.h" | ||||
| #include <QSerialPort> | ||||
| #ifndef _WIN32 | ||||
| #include <time.h> | ||||
| #endif | ||||
|  | ||||
| LedDeviceDMX::LedDeviceDMX(const QJsonObject &deviceConfig) | ||||
| 	: ProviderRs232() | ||||
| @@ -80,9 +82,14 @@ int LedDeviceDMX::write(const std::vector<ColorRgb> &ledValues) | ||||
| 	} | ||||
|  | ||||
| 	_rs232Port.setBreakEnabled(true); | ||||
| // Note Windows: There is no concept of ns sleeptime, the closest possible is 1ms but requested is 0,000176ms | ||||
| #ifndef _WIN32 | ||||
| 	nanosleep((const struct timespec[]){{0, 176000L}}, NULL);	// 176 uSec break time | ||||
| #endif | ||||
| 	_rs232Port.setBreakEnabled(false); | ||||
| #ifndef _WIN32 | ||||
| 	nanosleep((const struct timespec[]){{0, 12000L}}, NULL);	// 176 uSec make after break time | ||||
| #endif | ||||
|  | ||||
| #undef uberdebug | ||||
| #ifdef uberdebug | ||||
|   | ||||
| @@ -1,8 +1,14 @@ | ||||
| find_package(PythonLibs 3.5 REQUIRED) | ||||
|  | ||||
| # Include the python directory. Also include the parent (which is for example /usr/include) | ||||
| # which may be required when it is not includes by the (cross-) compiler by default. | ||||
| include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	find_package(Python3 COMPONENTS Interpreter Development REQUIRED) | ||||
| 	include_directories(${Python3_INCLUDE_DIRS} ${Python3_INCLUDE_DIRS}/..) | ||||
| 	add_compile_definitions(PYTHON_VERSION_MAJOR_MINOR=${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}) | ||||
| else() | ||||
| 	find_package (PythonLibs ${PYTHON_VERSION_STRING} EXACT) # Maps PythonLibs to the PythonInterp version of the main cmake | ||||
| 	include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | ||||
| 	add_definitions(-DPYTHON_VERSION_MAJOR_MINOR=${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}) | ||||
| endif() | ||||
|  | ||||
| # Define the current source locations | ||||
| SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/python) | ||||
| @@ -17,5 +23,10 @@ add_library(python | ||||
| target_link_libraries(python | ||||
| 	effectengine | ||||
| 	hyperion-utils | ||||
| 	${PYTHON_LIBRARIES} | ||||
| ) | ||||
|  | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	target_link_libraries( python ${Python3_LIBRARIES} ) | ||||
| else() | ||||
| 	target_link_libraries( python ${PYTHON_LIBRARIES} ) | ||||
| endif() | ||||
|   | ||||
| @@ -15,19 +15,31 @@ | ||||
| // modules to init | ||||
| #include <effectengine/EffectModule.h> | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| 	#define STRINGIFY2(x) #x | ||||
| 	#define STRINGIFY(x) STRINGIFY2(x) | ||||
| #endif | ||||
|  | ||||
| PythonInit::PythonInit() | ||||
| { | ||||
| 	// register modules | ||||
| 	EffectModule::registerHyperionExtensionModule(); | ||||
|  | ||||
| 	// set Python module path when exists | ||||
| 	const wchar_t *pythonPath = Py_DecodeLocale((QDir::cleanPath(qApp->applicationDirPath() + "/../lib/python")).toLatin1().data(), nullptr); | ||||
| 	if(QDir(QString::fromWCharArray(pythonPath)).exists()) | ||||
| 	wchar_t *pythonPath = Py_DecodeLocale((QDir::cleanPath(qApp->applicationDirPath() + "/../lib/python")).toLatin1().data(), nullptr); | ||||
| 	#ifdef _WIN32 | ||||
| 		pythonPath = Py_DecodeLocale((QDir::cleanPath(qApp->applicationDirPath())).toLatin1().data(), nullptr); | ||||
| 		pythonPath =  wcscat(pythonPath, L"/python" STRINGIFY(PYTHON_VERSION_MAJOR_MINOR) ".zip"); | ||||
| 		if(QFile(QString::fromWCharArray(pythonPath)).exists()) | ||||
| 	#else | ||||
| 		if(QDir(QString::fromWCharArray(pythonPath)).exists()) | ||||
| 	#endif | ||||
|  | ||||
| 	{ | ||||
| 		Py_NoSiteFlag++; | ||||
| 		Py_SetPath(pythonPath); | ||||
| 		PyMem_RawFree(pythonPath); | ||||
| 	} | ||||
| 	delete pythonPath; | ||||
|  | ||||
| 	// init Python | ||||
| 	Debug(Logger::getInstance("DAEMON"), "Initializing Python interpreter"); | ||||
|   | ||||
| @@ -3,13 +3,21 @@ | ||||
|  | ||||
| #include <iostream> | ||||
| #include <algorithm> | ||||
| #include <syslog.h> | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| #include <syslog.h> | ||||
| #elif _WIN32 | ||||
| #include <windows.h> | ||||
| #include <Shlwapi.h> | ||||
| #pragma comment(lib, "Shlwapi.lib") | ||||
| #endif | ||||
| #include <QFileInfo> | ||||
| #include <time.h> | ||||
|  | ||||
| static const char * LogLevelStrings[]   = { "", "DEBUG", "INFO", "WARNING", "ERROR" }; | ||||
| #ifndef _WIN32 | ||||
| static const int    LogLevelSysLog[]    = { LOG_DEBUG, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR }; | ||||
| #endif | ||||
| static unsigned int loggerCount         = 0; | ||||
| static unsigned int loggerId            = 0; | ||||
|  | ||||
| @@ -99,8 +107,19 @@ Logger::Logger ( QString name, LogLevel minLevel ) | ||||
| { | ||||
| #ifdef __GLIBC__ | ||||
|     const char* _appname_char = program_invocation_short_name; | ||||
| #else | ||||
| #elif !defined(_WIN32) | ||||
|     const char* _appname_char = getprogname(); | ||||
| #else | ||||
| 	char fileName[MAX_PATH]; | ||||
| 	char *_appname_char; | ||||
| 	HINSTANCE hinst = GetModuleHandle(NULL); | ||||
| 	if (GetModuleFileNameA(hinst, fileName, sizeof(fileName))) | ||||
| 	{ | ||||
| 		_appname_char = PathFindFileName(fileName); | ||||
| 		*(PathFindExtension(fileName)) = 0; | ||||
| 	} | ||||
| 	else | ||||
| 		_appname_char = "unknown"; | ||||
| #endif | ||||
| 	_appname = QString(_appname_char).toLower(); | ||||
|  | ||||
| @@ -108,7 +127,9 @@ Logger::Logger ( QString name, LogLevel minLevel ) | ||||
|  | ||||
| 	if (_syslogEnabled && loggerCount == 1 ) | ||||
| 	{ | ||||
| 		#ifndef _WIN32 | ||||
| 		openlog (_appname_char, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0); | ||||
| 		#endif | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -116,8 +137,10 @@ Logger::~Logger() | ||||
| { | ||||
| 	//Debug(this, "logger '%s' destroyed", QSTRING_CSTR(_name) ); | ||||
| 	loggerCount--; | ||||
| #ifndef _WIN32 | ||||
| 	if ( loggerCount == 0 ) | ||||
| 		closelog(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void Logger::Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...) | ||||
| @@ -142,8 +165,10 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u | ||||
|  | ||||
| 		std::cout << QString("[" + repMsg.appName + " " + repMsg.loggerName + "] <" + LogLevelStrings[repMsg.level] + "> " + repMsg.message).toStdString() << std::endl; | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| 		if ( _syslogEnabled && repMsg.level >= Logger::WARNING ) | ||||
| 			syslog (LogLevelSysLog[repMsg.level], "Previous line repeats %d times", _repeatCount); | ||||
| #endif | ||||
|  | ||||
| 		_repeatCount = 0; | ||||
| 	}; | ||||
| @@ -185,10 +210,10 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u | ||||
| 		} | ||||
|  | ||||
| 		std::cout << QString("[" + _appname + " " + _name + "] <" + LogLevelStrings[level] + "> " + location + msg).toStdString() << std::endl; | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| 		if ( _syslogEnabled && level >= Logger::WARNING ) | ||||
| 			syslog (LogLevelSysLog[level], "%s", msg); | ||||
|  | ||||
| #endif | ||||
| 		_repeatMessage = logMsg; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,19 @@ | ||||
| #ifdef _WIN32 | ||||
| #include <utils/Logger.h> | ||||
| #include <QString> | ||||
| #include <QByteArray> | ||||
| namespace Process { | ||||
|  | ||||
| void restartHyperion(bool asNewProcess){} | ||||
|  | ||||
| QByteArray command_exec(QString cmd, QByteArray data) | ||||
| { | ||||
| 	return QSTRING_CSTR(QString()); | ||||
| } | ||||
| }; | ||||
|  | ||||
| #else | ||||
|  | ||||
| #include <utils/Process.h> | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| @@ -55,3 +71,5 @@ QByteArray command_exec(QString cmd, QByteArray data) | ||||
| } | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -58,9 +58,9 @@ void RgbChannelAdjustment::apply(uint8_t input, uint8_t brightness, uint8_t & re | ||||
|  | ||||
| 	if (!_initialized[input]) | ||||
| 	{ | ||||
| 		_mapping[RED  ][input] = qMin( ((_brightness * input * _adjust[RED  ]) / 65025), UINT8_MAX); | ||||
| 		_mapping[GREEN][input] = qMin( ((_brightness * input * _adjust[GREEN]) / 65025), UINT8_MAX); | ||||
| 		_mapping[BLUE ][input] = qMin( ((_brightness * input * _adjust[BLUE ]) / 65025), UINT8_MAX); | ||||
| 		_mapping[RED  ][input] = qMin( ((_brightness * input * _adjust[RED  ]) / 65025), (int)UINT8_MAX); | ||||
| 		_mapping[GREEN][input] = qMin( ((_brightness * input * _adjust[GREEN]) / 65025), (int)UINT8_MAX); | ||||
| 		_mapping[BLUE ][input] = qMin( ((_brightness * input * _adjust[BLUE ]) / 65025), (int)UINT8_MAX); | ||||
| 		_initialized[input] = true; | ||||
| 	} | ||||
| 	red   = _mapping[RED  ][input]; | ||||
|   | ||||
| @@ -2,34 +2,21 @@ | ||||
|  | ||||
| #include <QHostInfo> | ||||
| #include <QSysInfo> | ||||
| #include <iostream> | ||||
| #include <sys/utsname.h> | ||||
| #include "HyperionConfig.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <limits.h> | ||||
| #include <stdarg.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
| SysInfo* SysInfo::_instance = nullptr; | ||||
|  | ||||
| SysInfo::SysInfo() | ||||
| 	: QObject() | ||||
| { | ||||
| 	SysInfo::QUnixOSVersion v; | ||||
| 	findUnixOsVersion(v); | ||||
|  | ||||
| 	_sysinfo.kernelType     = kernelType(); | ||||
| 	_sysinfo.kernelVersion  = kernelVersion(); | ||||
| 	_sysinfo.architecture   = currentCpuArchitecture(); | ||||
| 	_sysinfo.kernelType     = QSysInfo::kernelType(); | ||||
| 	_sysinfo.kernelVersion  = QSysInfo::kernelVersion(); | ||||
| 	_sysinfo.architecture   = QSysInfo::currentCpuArchitecture(); | ||||
| 	_sysinfo.wordSize       = QString::number(QSysInfo::WordSize); | ||||
| 	_sysinfo.productType    = v.productType; | ||||
| 	_sysinfo.productVersion = v.productVersion; | ||||
| 	_sysinfo.prettyName     = v.prettyName; | ||||
| 	_sysinfo.productType    = QSysInfo::productType(); | ||||
| 	_sysinfo.productVersion = QSysInfo::productVersion(); | ||||
| 	_sysinfo.prettyName     = QSysInfo::prettyProductName(); | ||||
| 	_sysinfo.hostName       = QHostInfo::localHostName(); | ||||
| 	_sysinfo.domainName       = QHostInfo::localDomainName(); | ||||
| 	_sysinfo.domainName     = QHostInfo::localDomainName(); | ||||
| } | ||||
|  | ||||
| SysInfo::~SysInfo() | ||||
| @@ -40,259 +27,6 @@ SysInfo::HyperionSysInfo SysInfo::get() | ||||
| { | ||||
| 	if ( SysInfo::_instance == nullptr ) | ||||
| 		SysInfo::_instance = new SysInfo(); | ||||
| 	 | ||||
|  | ||||
| 	return SysInfo::_instance->_sysinfo; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| QString SysInfo::kernelType() | ||||
| { | ||||
| #if defined(Q_OS_WIN) | ||||
| 	return QStringLiteral("winnt"); | ||||
| #elif defined(Q_OS_UNIX) | ||||
| 	struct utsname u; | ||||
| 	if (uname(&u) == 0) | ||||
| 		return QString::fromLatin1(u.sysname).toLower(); | ||||
| #endif | ||||
| 	return QString(); | ||||
| } | ||||
|  | ||||
| QString SysInfo::kernelVersion() | ||||
| { | ||||
| 	struct utsname u; | ||||
| 	if (uname(&u) == 0) | ||||
| 		return QString::fromLocal8Bit(u.release).toLower(); | ||||
|  | ||||
| 	return QString(); | ||||
| } | ||||
|  | ||||
| QString SysInfo::machineHostName() | ||||
| { | ||||
| #if defined(Q_OS_LINUX) | ||||
| 	// gethostname(3) on Linux just calls uname(2), so do it ourselves and avoid a memcpy | ||||
| 	struct utsname u; | ||||
| 	if (uname(&u) == 0) | ||||
| 		return QString::fromLocal8Bit(u.nodename); | ||||
| #else | ||||
| 	char hostName[512]; | ||||
| 	if (gethostname(hostName, sizeof(hostName)) == -1) | ||||
| 		return QString(); | ||||
| 	hostName[sizeof(hostName) - 1] = '\0'; | ||||
| 	return QString::fromLocal8Bit(hostName); | ||||
| #endif | ||||
| 	return QString(); | ||||
| } | ||||
|  | ||||
|  | ||||
| QString SysInfo::currentCpuArchitecture() | ||||
| { | ||||
| #if defined(Q_OS_UNIX) | ||||
| 	long ret = -1; | ||||
| 	struct utsname u; | ||||
|  | ||||
| 	if (ret == -1) | ||||
| 		ret = uname(&u); | ||||
|  | ||||
| 	// we could use detectUnixVersion() above, but we only need a field no other function does | ||||
| 	if (ret != -1) | ||||
| 	{ | ||||
| 		// the use of QT_BUILD_INTERNAL here is simply to ensure all branches build | ||||
| 		// as we don't often build on some of the less common platforms | ||||
| #  if defined(Q_PROCESSOR_ARM) | ||||
| 		if (strcmp(u.machine, "aarch64") == 0) | ||||
| 			return QStringLiteral("arm64"); | ||||
| 		if (strncmp(u.machine, "armv", 4) == 0) | ||||
| 			return QStringLiteral("arm"); | ||||
| #  endif | ||||
| #  if defined(Q_PROCESSOR_POWER) | ||||
| 		// harmonize "powerpc" and "ppc" to "power" | ||||
| 		if (strncmp(u.machine, "ppc", 3) == 0) | ||||
| 			return QLatin1String("power") + QLatin1String(u.machine + 3); | ||||
| 		if (strncmp(u.machine, "powerpc", 7) == 0) | ||||
| 			return QLatin1String("power") + QLatin1String(u.machine + 7); | ||||
| 		if (strcmp(u.machine, "Power Macintosh") == 0) | ||||
| 			return QLatin1String("power"); | ||||
| #  endif | ||||
| #  if defined(Q_PROCESSOR_X86) | ||||
| 		// harmonize all "i?86" to "i386" | ||||
| 		if (strlen(u.machine) == 4 && u.machine[0] == 'i' && u.machine[2] == '8' && u.machine[3] == '6') | ||||
| 			return QStringLiteral("i386"); | ||||
| 		if (strcmp(u.machine, "amd64") == 0) // Solaris | ||||
| 			return QStringLiteral("x86_64"); | ||||
| #  endif | ||||
| 		return QString::fromLatin1(u.machine); | ||||
| 	} | ||||
| #endif | ||||
| 	return QString(); | ||||
| } | ||||
|  | ||||
| bool SysInfo::findUnixOsVersion(SysInfo::QUnixOSVersion &v) | ||||
| { | ||||
| 	if (readEtcOsRelease(v)) | ||||
| 		return true; | ||||
| 	if (readEtcLsbRelease(v)) | ||||
| 		return true; | ||||
| #if defined(Q_OS_LINUX) | ||||
| 	if (readEtcRedHatRelease(v)) | ||||
| 		return true; | ||||
| 	if (readEtcDebianVersion(v)) | ||||
| 		return true; | ||||
| #endif | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
|  | ||||
| QByteArray SysInfo::getEtcFileFirstLine(const char *fileName) | ||||
| { | ||||
| 	QByteArray buffer = getEtcFileContent(fileName); | ||||
| 	if (buffer.isEmpty()) | ||||
| 		return QByteArray(); | ||||
|  | ||||
| 	const char *ptr = buffer.constData(); | ||||
| 	int eol = buffer.indexOf("\n"); | ||||
| 	return QByteArray(ptr, eol).trimmed(); | ||||
| } | ||||
|  | ||||
| bool SysInfo::readEtcRedHatRelease(SysInfo::QUnixOSVersion &v) | ||||
| { | ||||
| 	// /etc/redhat-release analysed should be a one line file | ||||
| 	// the format of its content is <Vendor_ID release Version> | ||||
| 	// i.e. "Red Hat Enterprise Linux Workstation release 6.5 (Santiago)" | ||||
| 	QByteArray line = getEtcFileFirstLine("/etc/redhat-release"); | ||||
| 	if (line.isEmpty()) | ||||
| 		return false; | ||||
|  | ||||
| 	v.prettyName = QString::fromLatin1(line); | ||||
|  | ||||
| 	const char keyword[] = "release "; | ||||
| 	int releaseIndex = line.indexOf(keyword); | ||||
| 	v.productType = QString::fromLatin1(line.mid(0, releaseIndex)).remove(QLatin1Char(' ')); | ||||
| 	int spaceIndex = line.indexOf(' ', releaseIndex + strlen(keyword)); | ||||
| 	v.productVersion = QString::fromLatin1(line.mid(releaseIndex + strlen(keyword), | ||||
| 													spaceIndex > -1 ? spaceIndex - releaseIndex - int(strlen(keyword)) : -1)); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool SysInfo::readEtcDebianVersion(SysInfo::QUnixOSVersion &v) | ||||
| { | ||||
| 	// /etc/debian_version analysed should be a one line file | ||||
| 	// the format of its content is <Release_ID/sid> | ||||
| 	// i.e. "jessie/sid" | ||||
| 	QByteArray line = getEtcFileFirstLine("/etc/debian_version"); | ||||
| 	if (line.isEmpty()) | ||||
| 		return false; | ||||
|  | ||||
| 	v.productType = QStringLiteral("Debian"); | ||||
| 	v.productVersion = QString::fromLatin1(line); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| QString SysInfo::unquote(const char *begin, const char *end) | ||||
| { | ||||
| 	if (*begin == '"') { | ||||
| 		Q_ASSERT(end[-1] == '"'); | ||||
| 		return QString::fromLatin1(begin + 1, end - begin - 2); | ||||
| 	} | ||||
| 	return QString::fromLatin1(begin, end - begin); | ||||
| } | ||||
|  | ||||
| QByteArray SysInfo::getEtcFileContent(const char *filename) | ||||
| { | ||||
| 	// we're avoiding QFile here | ||||
| 	int fd = open(filename, O_RDONLY); | ||||
| 	if (fd == -1) | ||||
| 		return QByteArray(); | ||||
|  | ||||
| 	struct stat sbuf; | ||||
| 	if (::fstat(fd, &sbuf) == -1) { | ||||
| 		close(fd); | ||||
| 		return QByteArray(); | ||||
| 	} | ||||
|  | ||||
| 	QByteArray buffer(sbuf.st_size, Qt::Uninitialized); | ||||
| 	buffer.resize(read(fd, buffer.data(), sbuf.st_size)); | ||||
| 	close(fd); | ||||
| 	return buffer; | ||||
| } | ||||
|  | ||||
| bool SysInfo::readEtcFile(SysInfo::QUnixOSVersion &v, const char *filename, | ||||
| 						const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey) | ||||
| { | ||||
|  | ||||
| 	QByteArray buffer = getEtcFileContent(filename); | ||||
| 	if (buffer.isEmpty()) | ||||
| 		return false; | ||||
|  | ||||
| 	const char *ptr = buffer.constData(); | ||||
| 	const char *end = buffer.constEnd(); | ||||
| 	const char *eol; | ||||
| 	QByteArray line; | ||||
| 	for ( ; ptr != end; ptr = eol + 1) { | ||||
| 		// find the end of the line after ptr | ||||
| 		eol = static_cast<const char *>(memchr(ptr, '\n', end - ptr)); | ||||
| 		if (!eol) | ||||
| 			eol = end - 1; | ||||
| 		line.setRawData(ptr, eol - ptr); | ||||
|  | ||||
| 		if (line.startsWith(idKey)) { | ||||
| 			ptr += idKey.length(); | ||||
| 			v.productType = unquote(ptr, eol); | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (line.startsWith(prettyNameKey)) { | ||||
| 			ptr += prettyNameKey.length(); | ||||
| 			v.prettyName = unquote(ptr, eol); | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (line.startsWith(versionKey)) { | ||||
| 			ptr += versionKey.length(); | ||||
| 			v.productVersion = unquote(ptr, eol); | ||||
| 			continue; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool SysInfo::readEtcOsRelease(SysInfo::QUnixOSVersion &v) | ||||
| { | ||||
| 	return readEtcFile(v, "/etc/os-release", QByteArrayLiteral("ID="), | ||||
| 					   QByteArrayLiteral("VERSION_ID="), QByteArrayLiteral("PRETTY_NAME=")); | ||||
| } | ||||
|  | ||||
| bool SysInfo::readEtcLsbRelease(SysInfo::QUnixOSVersion &v) | ||||
| { | ||||
| 	bool ok = readEtcFile(v, "/etc/lsb-release", QByteArrayLiteral("DISTRIB_ID="), | ||||
| 						  QByteArrayLiteral("DISTRIB_RELEASE="), QByteArrayLiteral("DISTRIB_DESCRIPTION=")); | ||||
| 	if (ok && (v.prettyName.isEmpty() || v.prettyName == v.productType)) { | ||||
| 		// some distributions have redundant information for the pretty name, | ||||
| 		// so try /etc/<lowercasename>-release | ||||
|  | ||||
| 		// we're still avoiding QFile here | ||||
| 		QByteArray distrorelease = "/etc/" + v.productType.toLatin1().toLower() + "-release"; | ||||
| 		int fd = open(distrorelease, O_RDONLY); | ||||
| 		if (fd != -1) { | ||||
| 			struct stat sbuf; | ||||
| 			if (::fstat(fd, &sbuf) != -1 && sbuf.st_size > v.prettyName.length()) { | ||||
| 				// file apparently contains interesting information | ||||
| 				QByteArray buffer(sbuf.st_size, Qt::Uninitialized); | ||||
| 				buffer.resize(read(fd, buffer.data(), sbuf.st_size)); | ||||
| 				v.prettyName = QString::fromLatin1(buffer.trimmed()); | ||||
| 			} | ||||
| 			close(fd); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// some distributions have a /etc/lsb-release file that does not provide the values | ||||
| 	// we are looking for, i.e. DISTRIB_ID, DISTRIB_RELEASE and DISTRIB_DESCRIPTION. | ||||
| 	// Assuming that neither DISTRIB_ID nor DISTRIB_RELEASE were found, or contained valid values, | ||||
| 	// returning false for readEtcLsbRelease will allow further /etc/<lowercasename>-release parsing. | ||||
| 	return ok && !(v.productType.isEmpty() && v.productVersion.isEmpty()); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,8 +6,9 @@ | ||||
| #include <QJsonObject> | ||||
|  | ||||
| // bonjour | ||||
| #ifdef ENABLE_AVAHI | ||||
| #include <bonjour/bonjourserviceregister.h> | ||||
|  | ||||
| #endif | ||||
| // netUtil | ||||
| #include <utils/NetUtils.h> | ||||
|  | ||||
| @@ -56,7 +57,7 @@ void WebServer::onServerStarted (quint16 port) | ||||
| 	_inited= true; | ||||
|  | ||||
| 	Info(_log, "Started on port %d name '%s'", port ,_server->getServerName().toStdString().c_str()); | ||||
|  | ||||
| #ifdef ENABLE_AVAHI | ||||
| 	if(_serviceRegister == nullptr) | ||||
| 	{ | ||||
| 		_serviceRegister = new BonjourServiceRegister(this); | ||||
| @@ -68,6 +69,7 @@ void WebServer::onServerStarted (quint16 port) | ||||
| 		_serviceRegister = new BonjourServiceRegister(this); | ||||
| 		_serviceRegister->registerService("_hyperiond-http._tcp", port); | ||||
| 	} | ||||
| #endif | ||||
| 	emit stateChange(true); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,10 @@ if(ENABLE_FB) | ||||
| 	add_subdirectory(hyperion-framebuffer) | ||||
| endif() | ||||
|  | ||||
| if(ENABLE_QT) | ||||
| 	add_subdirectory(hyperion-qt) | ||||
| endif() | ||||
|  | ||||
| if(ENABLE_OSX) | ||||
| 	add_subdirectory(hyperion-osx) | ||||
| endif() | ||||
|   | ||||
| @@ -41,10 +41,10 @@ if (ENABLE_AMLOGIC) | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_aml" ) | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT "hyperion_aml" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_aml" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT "hyperion_aml" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -42,10 +42,10 @@ target_link_libraries( ${PROJECT_NAME} | ||||
| 	Qt5::Network | ||||
| ) | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_dispmanx" ) | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "hyperion_dispmanx" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_dispmanx" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "hyperion_dispmanx" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -40,10 +40,10 @@ if (ENABLE_AMLOGIC) | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_framebuffer" ) | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "hyperion_framebuffer" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_framebuffer" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "hyperion_framebuffer" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -34,10 +34,10 @@ target_link_libraries( ${PROJECT_NAME} | ||||
| 	Qt5::Network | ||||
| ) | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_osx" ) | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT "hyperion_osx" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_osx" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT "hyperion_osx" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -20,6 +20,7 @@ set(Hyperion_QT_SOURCES | ||||
| add_executable(${PROJECT_NAME} | ||||
| 	${Hyperion_QT_HEADERS} | ||||
| 	${Hyperion_QT_SOURCES} | ||||
| 	${WIN_RC_ICON_FILE} | ||||
| ) | ||||
|  | ||||
| target_link_libraries(${PROJECT_NAME} | ||||
| @@ -33,10 +34,14 @@ target_link_libraries(${PROJECT_NAME} | ||||
| 	Qt5::Network | ||||
| ) | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| if(NOT WIN32) | ||||
| 	install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_qt" ) | ||||
| else() | ||||
| 	install ( TARGETS ${PROJECT_NAME} DESTINATION "bin" COMPONENT "hyperion_qt" ) | ||||
| endif() | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "hyperion_qt" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_qt" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "hyperion_qt" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -3,7 +3,7 @@ project(hyperion-remote) | ||||
|  | ||||
| find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED) | ||||
|  | ||||
| # The following I do not undrstand completely... | ||||
| # The following I do not understand completely... | ||||
| # libQtCore.so uses some hardcoded library path inside which are incorrect after copying the file RPi file system | ||||
| # Therefore, an extra path is needed on which to find the required libraries | ||||
| IF ( EXISTS ${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf ) | ||||
| @@ -19,7 +19,9 @@ set(hyperion-remote_SOURCES | ||||
|  | ||||
| add_executable(${PROJECT_NAME} | ||||
| 	${hyperion-remote_HEADERS} | ||||
| 	${hyperion-remote_SOURCES}) | ||||
| 	${hyperion-remote_SOURCES} | ||||
| 	${WIN_RC_ICON_FILE} | ||||
| ) | ||||
|  | ||||
| target_link_libraries(${PROJECT_NAME} | ||||
| 	effectengine | ||||
| @@ -36,10 +38,14 @@ if (ENABLE_AMLOGIC) | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| if(NOT WIN32) | ||||
| 	install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_remote" ) | ||||
| else() | ||||
| 	install ( TARGETS ${PROJECT_NAME} DESTINATION "bin" COMPONENT "hyperion_remote" ) | ||||
| endif() | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT "hyperion_remote" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_remote" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT "hyperion_remote" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -58,8 +58,9 @@ int getInstaneIdbyName(const QJsonObject & reply, const QString name){ | ||||
|  | ||||
| int main(int argc, char * argv[]) | ||||
| { | ||||
| #ifndef _WIN32 | ||||
| 	setenv("AVAHI_COMPAT_NOWARN", "1", 1); | ||||
|  | ||||
| #endif | ||||
| 	std::cout | ||||
| 		<< "hyperion-remote:" << std::endl | ||||
| 		<< "\tVersion   : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl | ||||
|   | ||||
| @@ -40,10 +40,10 @@ if (ENABLE_AMLOGIC) | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_v4l2" ) | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT "hyperion_v4l2" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_v4l2" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT "hyperion_v4l2" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -38,10 +38,10 @@ target_link_libraries(${PROJECT_NAME} | ||||
| 	Qt5::Network | ||||
| ) | ||||
|  | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_x11" ) | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT "hyperion_x11" ) | ||||
| 	install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "hyperion_x11" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT "hyperion_x11" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|   | ||||
| @@ -1,178 +1,12 @@ | ||||
| find_package(PythonLibs 3.4 REQUIRED) | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	find_package(Python3 COMPONENTS Interpreter Development REQUIRED) | ||||
| 	include_directories(${Python3_INCLUDE_DIRS} ${Python3_INCLUDE_DIRS}/..) | ||||
| else() | ||||
| 	find_package (PythonLibs ${PYTHON_VERSION_STRING} EXACT) # Maps PythonLibs to the PythonInterp version of the main cmake | ||||
| 	include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | ||||
| endif() | ||||
|  | ||||
| find_package(Qt5Widgets REQUIRED) | ||||
| include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | ||||
|  | ||||
| macro(InstallDependencies TARGET INSTALL_COMPONENT) | ||||
| 	set(TARGET_FILE ${CMAKE_BINARY_DIR}/bin/${TARGET}) | ||||
| 	set(SYSTEM_LIBS_SKIP | ||||
| #		"libbsd" | ||||
| 		"libc" | ||||
| #		"libdbus-1" | ||||
| 		"libdl" | ||||
| 		"libexpat" | ||||
| 		"libfontconfig" | ||||
| 		"libfreetype" | ||||
| 		"libgcc_s" | ||||
| 		"libgcrypt" | ||||
| 		"libGL" | ||||
| 		"libGLdispatch" | ||||
| 		"libglib-2" | ||||
| 		"libGLX" | ||||
| 		"libgpg-error" | ||||
| #		"liblz4" | ||||
| #		"liblzma" | ||||
| 		"libm" | ||||
| 		"libpthread" | ||||
| 		"librt" | ||||
| 		"libstdc++" | ||||
| #		"libsystemd" | ||||
| 		"libudev" | ||||
| 		"libusb-1" | ||||
| 		"libutil" | ||||
| 		"libX11" | ||||
| #		"libXau" | ||||
| #		"libxcb" | ||||
| #		"libXdmcp" | ||||
| #		"libXext" | ||||
| #		"libXrender" | ||||
| 		"libz" | ||||
| 	) | ||||
|  | ||||
| 	if(EXISTS ${TARGET_FILE}) | ||||
| 		include(GetPrerequisites) | ||||
|  | ||||
| 		if (APPLE) | ||||
| 			set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) | ||||
| 		endif(APPLE) | ||||
|  | ||||
| 		# Extract dependencies ignoring the system ones | ||||
| 		get_prerequisites(${TARGET_FILE} DEPENDENCIES 0 1 "" "") | ||||
|  | ||||
| 		# Append symlink and non-symlink dependencies to the list | ||||
| 		set(PREREQUISITE_LIBS "") | ||||
| 		foreach(DEPENDENCY ${DEPENDENCIES}) | ||||
| 			get_filename_component(resolved ${DEPENDENCY} NAME_WE) | ||||
| 			list(FIND SYSTEM_LIBS_SKIP ${resolved} _index) | ||||
| 			if (${_index} GREATER -1) | ||||
| 				continue() # Skip system libraries | ||||
| 			else() | ||||
| 				gp_resolve_item("${TARGET_FILE}" "${DEPENDENCY}" "" "" resolved_file) | ||||
| 				get_filename_component(resolved_file ${resolved_file} ABSOLUTE) | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${resolved_file}) | ||||
| 				get_filename_component(file_canonical ${resolved_file} REALPATH) | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 			endif() | ||||
| 		endforeach() | ||||
|  | ||||
| 		# Append the OpenSSL library to the list | ||||
| 		find_package(OpenSSL 1.0.0 REQUIRED) | ||||
| 		if (OPENSSL_FOUND) | ||||
| 			foreach(openssl_lib ${OPENSSL_LIBRARIES}) | ||||
| 				get_prerequisites(${openssl_lib} openssl_deps 0 1 "" "") | ||||
|  | ||||
| 				foreach(openssl_dep ${openssl_deps}) | ||||
| 					get_filename_component(resolved ${openssl_dep} NAME_WE) | ||||
| 					list(FIND SYSTEM_LIBS_SKIP ${resolved} _index) | ||||
| 					if (${_index} GREATER -1) | ||||
| 						continue() # Skip system libraries | ||||
| 					else() | ||||
| 						gp_resolve_item("${openssl_lib}" "${openssl_dep}" "" "" resolved_file) | ||||
| 						get_filename_component(resolved_file ${resolved_file} ABSOLUTE) | ||||
| 						gp_append_unique(PREREQUISITE_LIBS ${resolved_file}) | ||||
| 						get_filename_component(file_canonical ${resolved_file} REALPATH) | ||||
| 						gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 					endif() | ||||
| 				endforeach() | ||||
|  | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${openssl_lib}) | ||||
| 				get_filename_component(file_canonical ${openssl_lib} REALPATH) | ||||
| 				gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 			endforeach() | ||||
| 		endif(OPENSSL_FOUND) | ||||
|  | ||||
| 		# Detect the Qt5 plugin directory, source: https://github.com/lxde/lxqt-qtplugin/blob/master/src/CMakeLists.txt | ||||
| 		get_target_property(QT_QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE} IMPORTED_LOCATION) | ||||
| 		execute_process( | ||||
| 			COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS | ||||
| 			OUTPUT_VARIABLE QT_PLUGINS_DIR | ||||
| 			OUTPUT_STRIP_TRAILING_WHITESPACE | ||||
| 		) | ||||
|  | ||||
| 		# Copy Qt plugins to 'share/hyperion/lib' | ||||
| 		if(QT_PLUGINS_DIR) | ||||
| 			foreach(PLUGIN "platforms" "sqldrivers" "imageformats") | ||||
| 				if(EXISTS ${QT_PLUGINS_DIR}/${PLUGIN}) | ||||
| 					file(GLOB files "${QT_PLUGINS_DIR}/${PLUGIN}/*") | ||||
| 					foreach(file ${files}) | ||||
| 						get_prerequisites(${file} PLUGINS 0 1 "" "") | ||||
|  | ||||
| 						foreach(DEPENDENCY ${PLUGINS}) | ||||
| 							get_filename_component(resolved ${DEPENDENCY} NAME_WE) | ||||
| 							list(FIND SYSTEM_LIBS_SKIP ${resolved} _index) | ||||
| 							if (${_index} GREATER -1) | ||||
| 								continue() # Skip system libraries | ||||
| 							else() | ||||
| 								gp_resolve_item("${file}" "${DEPENDENCY}" "" "" resolved_file) | ||||
| 								get_filename_component(resolved_file ${resolved_file} ABSOLUTE) | ||||
| 								gp_append_unique(PREREQUISITE_LIBS ${resolved_file}) | ||||
| 								get_filename_component(file_canonical ${resolved_file} REALPATH) | ||||
| 								gp_append_unique(PREREQUISITE_LIBS ${file_canonical}) | ||||
| 							endif() | ||||
| 						endforeach() | ||||
|  | ||||
| 						install( | ||||
| 							FILES ${file} | ||||
| 							DESTINATION "share/hyperion/lib/${PLUGIN}" | ||||
| 							COMPONENT "${INSTALL_COMPONENT}" | ||||
| 						) | ||||
| 					endforeach() | ||||
| 				endif() | ||||
| 			endforeach() | ||||
| 		endif(QT_PLUGINS_DIR) | ||||
|  | ||||
| 		# Create a qt.conf file in 'share/hyperion/bin' to override hard-coded search paths in Qt plugins | ||||
| 		file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=../lib/\n") | ||||
| 		install( | ||||
| 			FILES "${CMAKE_BINARY_DIR}/qt.conf" | ||||
| 			DESTINATION "share/hyperion/bin" | ||||
| 			COMPONENT "${INSTALL_COMPONENT}" | ||||
| 		) | ||||
|  | ||||
| 		# Copy dependencies to 'share/hyperion/lib' | ||||
| 		foreach(PREREQUISITE_LIB ${PREREQUISITE_LIBS}) | ||||
| 			install( | ||||
| 				FILES ${PREREQUISITE_LIB} | ||||
| 				DESTINATION "share/hyperion/lib" | ||||
| 				COMPONENT "${INSTALL_COMPONENT}" | ||||
| 			) | ||||
| 		endforeach() | ||||
|  | ||||
| 		# Detect the Python modules directory | ||||
| 		execute_process( | ||||
| 			COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(standard_lib=True))" | ||||
| 			OUTPUT_VARIABLE PYTHON_MODULES_DIR | ||||
| 			OUTPUT_STRIP_TRAILING_WHITESPACE | ||||
| 		) | ||||
|  | ||||
| 		# Copy Python modules to 'share/hyperion/lib/python' | ||||
| 		if (PYTHON_MODULES_DIR) | ||||
| 			install( | ||||
| 				DIRECTORY ${PYTHON_MODULES_DIR}/ | ||||
| 				DESTINATION "share/hyperion/lib/python" | ||||
| 				COMPONENT "${INSTALL_COMPONENT}" | ||||
| 			) | ||||
| 		endif(PYTHON_MODULES_DIR) | ||||
| 	else() | ||||
| 		# Run CMake after target was built to run get_prerequisites on ${TARGET_FILE} | ||||
| 		add_custom_command( | ||||
| 			TARGET ${TARGET} POST_BUILD | ||||
| 			COMMAND ${CMAKE_COMMAND} | ||||
| 			ARGS ${CMAKE_SOURCE_DIR} | ||||
| 			WORKING_DIRECTORY ${CMAKE_BINARY_DIR} | ||||
| 			VERBATIM | ||||
| 		) | ||||
| 	endif() | ||||
| endmacro() | ||||
|  | ||||
| add_executable(hyperiond | ||||
| 	hyperiond.h | ||||
| @@ -180,6 +14,7 @@ add_executable(hyperiond | ||||
| 	hyperiond.cpp | ||||
| 	systray.cpp | ||||
| 	main.cpp | ||||
| 	${WIN_RC_ICON_FILE} | ||||
| ) | ||||
|  | ||||
| target_link_libraries(hyperiond | ||||
| @@ -190,15 +25,23 @@ target_link_libraries(hyperiond | ||||
| 		flatbufserver | ||||
| 		protoserver | ||||
| 		webserver | ||||
| 		bonjour | ||||
| 		ssdp | ||||
| 		database | ||||
| 		python | ||||
| 		resources | ||||
| 		${PYTHON_LIBRARIES} | ||||
| 		Qt5::Widgets | ||||
| ) | ||||
|  | ||||
| if (NOT CMAKE_VERSION VERSION_LESS "3.12") | ||||
| 	target_link_libraries( hyperiond ${Python3_LIBRARIES} ) | ||||
| else() | ||||
| 	target_link_libraries( hyperiond ${PYTHON_LIBRARIES} ) | ||||
| endif() | ||||
|  | ||||
| if (ENABLE_AVAHI) | ||||
| 	target_link_libraries(hyperiond bonjour) | ||||
| endif () | ||||
|  | ||||
| if (ENABLE_AMLOGIC) | ||||
| 	target_link_libraries(hyperiond | ||||
| 		Qt5::Core | ||||
| @@ -241,23 +84,35 @@ if (ENABLE_QT) | ||||
| 	target_link_libraries(hyperiond	qt-grabber) | ||||
| endif () | ||||
|  | ||||
| install ( TARGETS hyperiond DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" ) | ||||
| install ( DIRECTORY ${CMAKE_SOURCE_DIR}/bin/service DESTINATION "share/hyperion/" COMPONENT  "${PLATFORM}" ) | ||||
| install ( FILES ${CMAKE_SOURCE_DIR}/effects/readme.txt DESTINATION "share/hyperion/effects" COMPONENT  "${PLATFORM}" ) | ||||
| install ( FILES ${CMAKE_SOURCE_DIR}/resources/icons/hyperion-icon-32px.png DESTINATION "share/hyperion/icons" COMPONENT "${PLATFORM}" ) | ||||
| if(NOT WIN32) | ||||
| 	install ( TARGETS hyperiond DESTINATION "share/hyperion/bin" COMPONENT "Hyperion" ) | ||||
| 	install ( DIRECTORY ${CMAKE_SOURCE_DIR}/bin/service DESTINATION "share/hyperion/" COMPONENT "Hyperion" ) | ||||
| 	install ( FILES ${CMAKE_SOURCE_DIR}/effects/readme.txt DESTINATION "share/hyperion/effects" COMPONENT "Hyperion" ) | ||||
| 	install ( FILES ${CMAKE_SOURCE_DIR}/resources/icons/hyperion-icon-32px.png DESTINATION "share/hyperion/icons" COMPONENT "Hyperion" ) | ||||
|  | ||||
| # Desktop file for hyperiond | ||||
| install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperiond_128.png DESTINATION "share/hyperion/desktop" COMPONENT "${PLATFORM}" ) | ||||
| install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperiond.desktop DESTINATION "share/hyperion/desktop" COMPONENT "${PLATFORM}" ) | ||||
| 	# Desktop file for hyperiond | ||||
| 	install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperiond_128.png DESTINATION "share/hyperion/desktop" COMPONENT "Hyperion" ) | ||||
| 	install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperiond.desktop DESTINATION "share/hyperion/desktop" COMPONENT "Hyperion" ) | ||||
| else() | ||||
| 	install ( TARGETS hyperiond DESTINATION "bin" COMPONENT "Hyperion" ) | ||||
| 	install ( FILES ${CMAKE_SOURCE_DIR}/effects/readme.txt DESTINATION "effects" COMPONENT "Hyperion" ) | ||||
|  | ||||
| 	#set( CMAKE_INSTALL_UCRT_LIBRARIES TRUE ) | ||||
| 	#set( CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE ) | ||||
| 	#include( InstallRequiredSystemLibraries ) | ||||
| endif() | ||||
|  | ||||
| if(CMAKE_HOST_UNIX) | ||||
| 	install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/hyperiond\" \"${CMAKE_BINARY_DIR}/symlink_hyperiond\" )" COMPONENT  "${PLATFORM}" ) | ||||
| 	install(FILES ${CMAKE_BINARY_DIR}/symlink_hyperiond DESTINATION "bin" RENAME hyperiond COMPONENT "${PLATFORM}" ) | ||||
| 	install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_hyperiond )" COMPONENT "${PLATFORM}" ) | ||||
| endif(CMAKE_HOST_UNIX) | ||||
|  | ||||
| 	install( CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/hyperiond\" \"${CMAKE_BINARY_DIR}/symlink_hyperiond\" )" COMPONENT "Hyperion" ) | ||||
| 	install( FILES ${CMAKE_BINARY_DIR}/symlink_hyperiond DESTINATION "bin" RENAME hyperiond COMPONENT "Hyperion" ) | ||||
| 	install( CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_hyperiond )" COMPONENT "Hyperion" ) | ||||
| endif() | ||||
|  | ||||
| # Copy dependencies (not for OSX) | ||||
| if (NOT ENABLE_OSX) | ||||
| 	InstallDependencies("hyperiond" ${PLATFORM}) | ||||
| include(${CMAKE_SOURCE_DIR}/cmake/Dependencies.cmake) | ||||
|  | ||||
| if (NOT ENABLE_OSX AND NOT WIN32) # Unix | ||||
| 	DeployUnix("hyperiond") | ||||
| elseif(WIN32) # Windows | ||||
| 	DeployWindows("hyperiond") | ||||
| endif () | ||||
|   | ||||
							
								
								
									
										84
									
								
								src/hyperiond/detectProcess.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/hyperiond/detectProcess.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <QString> | ||||
| #include <QProcess> | ||||
| #include <QByteArray> | ||||
|  | ||||
| #ifdef WIN32 | ||||
| // psapi.h requires windows.h to be included | ||||
| #include <Windows.h> | ||||
| #include <Psapi.h> | ||||
| #endif | ||||
|  | ||||
| unsigned int getProcessIdsByProcessName(const char *processName, QStringList &listOfPids) | ||||
| { | ||||
|  | ||||
| 	// Clear content of returned list of PIDS | ||||
| 	listOfPids.clear(); | ||||
|  | ||||
| #if defined(WIN32) | ||||
| 	// Get the list of process identifiers. | ||||
| 	DWORD aProcesses[1024], cbNeeded, cProcesses; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) | ||||
| 		return 0; | ||||
|  | ||||
| 	// Calculate how many process identifiers were returned. | ||||
| 	cProcesses = cbNeeded / sizeof(DWORD); | ||||
|  | ||||
| 	// Search for a matching name for each process | ||||
| 	for (i = 0; i < cProcesses; i++) | ||||
| 	{ | ||||
| 		if (aProcesses[i] != 0) | ||||
| 		{ | ||||
| 			char szProcessName[MAX_PATH] = {0}; | ||||
|  | ||||
| 			DWORD processID = aProcesses[i]; | ||||
|  | ||||
| 			// Get a handle to the process. | ||||
| 			HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); | ||||
|  | ||||
| 			// Get the process name | ||||
| 			if (NULL != hProcess) | ||||
| 			{ | ||||
| 				HMODULE hMod; | ||||
| 				DWORD cbNeeded; | ||||
|  | ||||
| 				if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) | ||||
| 					GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName) / sizeof(char)); | ||||
|  | ||||
| 				// Release the handle to the process. | ||||
| 				CloseHandle(hProcess); | ||||
|  | ||||
| 				if (*szProcessName != 0 && strcmp(processName, szProcessName) == 0) | ||||
| 					listOfPids.append(QString::number(processID)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return listOfPids.count(); | ||||
|  | ||||
| #else | ||||
|  | ||||
| 	// Run pgrep, which looks through the currently running processses and lists the process IDs | ||||
| 	// which match the selection criteria to stdout. | ||||
| 	QProcess process; | ||||
| 	process.start("pgrep", QStringList() << processName); | ||||
| 	process.waitForReadyRead(); | ||||
|  | ||||
| 	QByteArray bytes = process.readAllStandardOutput(); | ||||
|  | ||||
| 	process.terminate(); | ||||
| 	process.waitForFinished(); | ||||
| 	process.kill(); | ||||
|  | ||||
| 	// Output is something like "2472\n2323" for multiple instances | ||||
| 	if (bytes.isEmpty()) | ||||
| 		return 0; | ||||
|  | ||||
| 	listOfPids = QString(bytes).split("\n", QString::SkipEmptyParts); | ||||
| 	return listOfPids.count(); | ||||
|  | ||||
| #endif | ||||
| } | ||||
| @@ -1,4 +1,3 @@ | ||||
| #include <unistd.h> | ||||
| #include <cassert> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| @@ -18,12 +17,14 @@ | ||||
| #include <utils/Components.h> | ||||
| #include <utils/JsonUtils.h> | ||||
|  | ||||
| // bonjour browser | ||||
| #include <bonjour/bonjourbrowserwrapper.h> | ||||
| #include <HyperionConfig.h> // Required to determine the cmake options | ||||
|  | ||||
| // bonjour browser | ||||
| #ifdef ENABLE_AVAHI | ||||
| #include <bonjour/bonjourbrowserwrapper.h> | ||||
| #endif | ||||
| #include <jsonserver/JsonServer.h> | ||||
| #include <webserver/WebServer.h> | ||||
| #include <HyperionConfig.h> // Required to determine the cmake options | ||||
| #include "hyperiond.h" | ||||
|  | ||||
| // Flatbuffer Server | ||||
| @@ -53,28 +54,29 @@ | ||||
| // EffectFileHandler | ||||
| #include <effectengine/EffectFileHandler.h> | ||||
|  | ||||
| HyperionDaemon* HyperionDaemon::daemon = nullptr; | ||||
| HyperionDaemon *HyperionDaemon::daemon = nullptr; | ||||
|  | ||||
| HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, const bool& logLvlOverwrite) | ||||
| 	: QObject(parent) | ||||
| 	, _log(Logger::getInstance("DAEMON")) | ||||
| 	, _instanceManager(new HyperionIManager(rootPath, this)) | ||||
| 	, _authManager(new AuthManager(this)) | ||||
| 	, _bonjourBrowserWrapper(new BonjourBrowserWrapper()) | ||||
| 	, _netOrigin(new NetOrigin(this)) | ||||
| 	, _pyInit(new PythonInit()) | ||||
| 	, _webserver(nullptr) | ||||
| 	, _sslWebserver(nullptr) | ||||
| 	, _jsonServer(nullptr) | ||||
| 	, _v4l2Grabber(nullptr) | ||||
| 	, _dispmanx(nullptr) | ||||
| 	, _x11Grabber(nullptr) | ||||
| 	, _amlGrabber(nullptr) | ||||
| 	, _fbGrabber(nullptr) | ||||
| 	, _osxGrabber(nullptr) | ||||
| 	, _qtGrabber(nullptr) | ||||
| 	, _ssdp(nullptr) | ||||
| 	, _currVideoMode(VIDEO_2D) | ||||
| HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, const bool &logLvlOverwrite) | ||||
| 		: QObject(parent), _log(Logger::getInstance("DAEMON")) | ||||
| 		, _instanceManager(new HyperionIManager(rootPath, this)) | ||||
| 		, _authManager(new AuthManager(this)) | ||||
| #ifdef ENABLE_AVAHI | ||||
| 		, _bonjourBrowserWrapper(new BonjourBrowserWrapper()) | ||||
| #endif | ||||
| 		, _netOrigin(new NetOrigin(this)) | ||||
| 		, _pyInit(new PythonInit()) | ||||
| 		, _webserver(nullptr) | ||||
| 		, _sslWebserver(nullptr) | ||||
| 		, _jsonServer(nullptr) | ||||
| 		, _v4l2Grabber(nullptr) | ||||
| 		, _dispmanx(nullptr) | ||||
| 		, _x11Grabber(nullptr) | ||||
| 		, _amlGrabber(nullptr) | ||||
| 		, _fbGrabber(nullptr) | ||||
| 		, _osxGrabber(nullptr) | ||||
| 		, _qtGrabber(nullptr) | ||||
| 		, _ssdp(nullptr) | ||||
| 		, _currVideoMode(VIDEO_2D) | ||||
| { | ||||
| 	HyperionDaemon::daemon = this; | ||||
|  | ||||
| @@ -83,18 +85,18 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, const bo | ||||
| 	qRegisterMetaType<hyperion::Components>("hyperion::Components"); | ||||
| 	qRegisterMetaType<settings::type>("settings::type"); | ||||
| 	qRegisterMetaType<VideoMode>("VideoMode"); | ||||
| 	qRegisterMetaType<QMap<quint8,QJsonObject>>("QMap<quint8,QJsonObject>"); | ||||
| 	qRegisterMetaType<QMap<quint8, QJsonObject>>("QMap<quint8,QJsonObject>"); | ||||
| 	qRegisterMetaType<std::vector<ColorRgb>>("std::vector<ColorRgb>"); | ||||
|  | ||||
| 	// init settings | ||||
| 	_settingsManager = new SettingsManager(0,this); | ||||
| 	_settingsManager = new SettingsManager(0, this); | ||||
|  | ||||
| 	// set inital log lvl if the loglvl wasn't overwritten by arg | ||||
| 	if(!logLvlOverwrite) | ||||
| 	if (!logLvlOverwrite) | ||||
| 		handleSettingsUpdate(settings::LOGGER, getSetting(settings::LOGGER)); | ||||
|  | ||||
| 	// init EffectFileHandler | ||||
| 	EffectFileHandler* efh = new EffectFileHandler(rootPath, getSetting(settings::EFFECTS), this); | ||||
| 	EffectFileHandler *efh = new EffectFileHandler(rootPath, getSetting(settings::EFFECTS), this); | ||||
| 	connect(this, &HyperionDaemon::settingsChanged, efh, &EffectFileHandler::handleSettingsUpdate); | ||||
|  | ||||
| 	// connect and apply settings for AuthManager | ||||
| @@ -122,10 +124,10 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, const bo | ||||
| 	// return videoMode changes from Daemon to HyperionIManager | ||||
| 	connect(this, &HyperionDaemon::videoMode, _instanceManager, &HyperionIManager::newVideoMode); | ||||
|  | ||||
| 	// ---- grabber ----- | ||||
| 	#if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB) && !defined(ENABLE_X11) && !defined(ENABLE_AMLOGIC) | ||||
| 		Warning(_log, "No platform capture can be instantiated, because all grabbers have been left out from the build"); | ||||
| 	#endif | ||||
| // ---- grabber ----- | ||||
| #if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB) && !defined(ENABLE_X11) && !defined(ENABLE_AMLOGIC) && !defined(ENABLE_QT) | ||||
| 	Warning(_log, "No platform capture can be instantiated, because all grabbers have been left out from the build"); | ||||
| #endif | ||||
|  | ||||
| 	// init system capture (framegrabber) | ||||
| 	handleSettingsUpdate(settings::SYSTEMCAPTURE, getSetting(settings::SYSTEMCAPTURE)); | ||||
| @@ -144,9 +146,9 @@ HyperionDaemon::~HyperionDaemon() | ||||
| 	delete _pyInit; | ||||
| } | ||||
|  | ||||
| void HyperionDaemon::setVideoMode(const VideoMode& mode) | ||||
| void HyperionDaemon::setVideoMode(const VideoMode &mode) | ||||
| { | ||||
| 	if(_currVideoMode != mode) | ||||
| 	if (_currVideoMode != mode) | ||||
| 	{ | ||||
| 		_currVideoMode = mode; | ||||
| 		emit videoMode(mode); | ||||
| @@ -177,7 +179,9 @@ void HyperionDaemon::freeObjects() | ||||
| 	// stop Hyperions (non blocking) | ||||
| 	_instanceManager->stopAll(); | ||||
|  | ||||
| #ifdef ENABLE_AVAHI | ||||
| 	delete _bonjourBrowserWrapper; | ||||
| #endif | ||||
| 	delete _amlGrabber; | ||||
| 	delete _dispmanx; | ||||
| 	delete _fbGrabber; | ||||
| @@ -185,19 +189,21 @@ void HyperionDaemon::freeObjects() | ||||
| 	delete _qtGrabber; | ||||
| 	delete _v4l2Grabber; | ||||
|  | ||||
| 	_v4l2Grabber           = nullptr; | ||||
| 	_v4l2Grabber = nullptr; | ||||
| #ifdef ENABLE_AVAHI | ||||
| 	_bonjourBrowserWrapper = nullptr; | ||||
| 	_amlGrabber            = nullptr; | ||||
| 	_dispmanx              = nullptr; | ||||
| 	_fbGrabber             = nullptr; | ||||
| 	_osxGrabber            = nullptr; | ||||
| 	_qtGrabber             = nullptr; | ||||
| 	_flatBufferServer      = nullptr; | ||||
| 	_protoServer           = nullptr; | ||||
| 	_ssdp                  = nullptr; | ||||
| 	_webserver             = nullptr; | ||||
| 	_sslWebserver          = nullptr; | ||||
| 	_jsonServer            = nullptr; | ||||
| #endif | ||||
| 	_amlGrabber = nullptr; | ||||
| 	_dispmanx = nullptr; | ||||
| 	_fbGrabber = nullptr; | ||||
| 	_osxGrabber = nullptr; | ||||
| 	_qtGrabber = nullptr; | ||||
| 	_flatBufferServer = nullptr; | ||||
| 	_protoServer = nullptr; | ||||
| 	_ssdp = nullptr; | ||||
| 	_webserver = nullptr; | ||||
| 	_sslWebserver = nullptr; | ||||
| 	_jsonServer = nullptr; | ||||
| } | ||||
|  | ||||
| void HyperionDaemon::startNetworkServices() | ||||
| @@ -208,93 +214,97 @@ void HyperionDaemon::startNetworkServices() | ||||
|  | ||||
| 	// Create FlatBuffer server in thread | ||||
| 	_flatBufferServer = new FlatBufferServer(getSetting(settings::FLATBUFSERVER)); | ||||
| 	QThread* fbThread = new QThread(this); | ||||
| 	QThread *fbThread = new QThread(this); | ||||
| 	_flatBufferServer->moveToThread(fbThread); | ||||
| 	connect( fbThread, &QThread::started, _flatBufferServer, &FlatBufferServer::initServer ); | ||||
| 	connect( fbThread, &QThread::finished, _flatBufferServer, &QObject::deleteLater ); | ||||
| 	connect( fbThread, &QThread::finished, fbThread, &QObject::deleteLater ); | ||||
| 	connect(fbThread, &QThread::started, _flatBufferServer, &FlatBufferServer::initServer); | ||||
| 	connect(fbThread, &QThread::finished, _flatBufferServer, &QObject::deleteLater); | ||||
| 	connect(fbThread, &QThread::finished, fbThread, &QObject::deleteLater); | ||||
| 	connect(this, &HyperionDaemon::settingsChanged, _flatBufferServer, &FlatBufferServer::handleSettingsUpdate); | ||||
| 	fbThread->start(); | ||||
|  | ||||
| 	// Create Proto server in thread | ||||
| 	_protoServer = new ProtoServer(getSetting(settings::PROTOSERVER)); | ||||
| 	QThread* pThread = new QThread(this); | ||||
| 	QThread *pThread = new QThread(this); | ||||
| 	_protoServer->moveToThread(pThread); | ||||
| 	connect( pThread, &QThread::started, _protoServer, &ProtoServer::initServer ); | ||||
| 	connect( pThread, &QThread::finished, _protoServer, &QObject::deleteLater ); | ||||
| 	connect( pThread, &QThread::finished, pThread, &QObject::deleteLater ); | ||||
| 	connect( this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate ); | ||||
| 	connect(pThread, &QThread::started, _protoServer, &ProtoServer::initServer); | ||||
| 	connect(pThread, &QThread::finished, _protoServer, &QObject::deleteLater); | ||||
| 	connect(pThread, &QThread::finished, pThread, &QObject::deleteLater); | ||||
| 	connect(this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate); | ||||
| 	pThread->start(); | ||||
|  | ||||
| 	// Create Webserver in thread | ||||
| 	_webserver = new WebServer(getSetting(settings::WEBSERVER), false); | ||||
| 	QThread* wsThread = new QThread(this); | ||||
| 	QThread *wsThread = new QThread(this); | ||||
| 	_webserver->moveToThread(wsThread); | ||||
| 	connect( wsThread, &QThread::started, _webserver, &WebServer::initServer ); | ||||
| 	connect( wsThread, &QThread::finished, _webserver, &QObject::deleteLater ); | ||||
| 	connect( wsThread, &QThread::finished, wsThread, &QObject::deleteLater ); | ||||
| 	connect(wsThread, &QThread::started, _webserver, &WebServer::initServer); | ||||
| 	connect(wsThread, &QThread::finished, _webserver, &QObject::deleteLater); | ||||
| 	connect(wsThread, &QThread::finished, wsThread, &QObject::deleteLater); | ||||
| 	connect(this, &HyperionDaemon::settingsChanged, _webserver, &WebServer::handleSettingsUpdate); | ||||
| 	wsThread->start(); | ||||
|  | ||||
| 	// Create SSL Webserver in thread | ||||
| 	_sslWebserver = new WebServer(getSetting(settings::WEBSERVER), true); | ||||
| 	QThread* sslWsThread = new QThread(this); | ||||
| 	QThread *sslWsThread = new QThread(this); | ||||
| 	_sslWebserver->moveToThread(sslWsThread); | ||||
| 	connect( sslWsThread, &QThread::started, _sslWebserver, &WebServer::initServer ); | ||||
| 	connect( sslWsThread, &QThread::finished, _sslWebserver, &QObject::deleteLater ); | ||||
| 	connect( sslWsThread, &QThread::finished, sslWsThread, &QObject::deleteLater ); | ||||
| 	connect(sslWsThread, &QThread::started, _sslWebserver, &WebServer::initServer); | ||||
| 	connect(sslWsThread, &QThread::finished, _sslWebserver, &QObject::deleteLater); | ||||
| 	connect(sslWsThread, &QThread::finished, sslWsThread, &QObject::deleteLater); | ||||
| 	connect(this, &HyperionDaemon::settingsChanged, _sslWebserver, &WebServer::handleSettingsUpdate); | ||||
| 	sslWsThread->start(); | ||||
|  | ||||
| 	// Create SSDP server in thread | ||||
| 	_ssdp = new SSDPHandler(_webserver, getSetting(settings::FLATBUFSERVER).object()["port"].toInt(), getSetting(settings::JSONSERVER).object()["port"].toInt(),  getSetting(settings::GENERAL).object()["name"].toString()); | ||||
| 	QThread* ssdpThread = new QThread(this); | ||||
| 	_ssdp = new SSDPHandler(_webserver, getSetting(settings::FLATBUFSERVER).object()["port"].toInt(), getSetting(settings::JSONSERVER).object()["port"].toInt(), getSetting(settings::GENERAL).object()["name"].toString()); | ||||
| 	QThread *ssdpThread = new QThread(this); | ||||
| 	_ssdp->moveToThread(ssdpThread); | ||||
| 	connect( ssdpThread, &QThread::started, _ssdp, &SSDPHandler::initServer ); | ||||
| 	connect( ssdpThread, &QThread::finished, _ssdp, &QObject::deleteLater ); | ||||
| 	connect( ssdpThread, &QThread::finished, ssdpThread, &QObject::deleteLater ); | ||||
| 	connect( _webserver, &WebServer::stateChange, _ssdp, &SSDPHandler::handleWebServerStateChange); | ||||
| 	connect(ssdpThread, &QThread::started, _ssdp, &SSDPHandler::initServer); | ||||
| 	connect(ssdpThread, &QThread::finished, _ssdp, &QObject::deleteLater); | ||||
| 	connect(ssdpThread, &QThread::finished, ssdpThread, &QObject::deleteLater); | ||||
| 	connect(_webserver, &WebServer::stateChange, _ssdp, &SSDPHandler::handleWebServerStateChange); | ||||
| 	connect(this, &HyperionDaemon::settingsChanged, _ssdp, &SSDPHandler::handleSettingsUpdate); | ||||
| 	ssdpThread->start(); | ||||
| } | ||||
|  | ||||
| void HyperionDaemon::handleSettingsUpdate(const settings::type& settingsType, const QJsonDocument& config) | ||||
| void HyperionDaemon::handleSettingsUpdate(const settings::type &settingsType, const QJsonDocument &config) | ||||
| { | ||||
| 	if(settingsType == settings::LOGGER) | ||||
| 	if (settingsType == settings::LOGGER) | ||||
| 	{ | ||||
| 		const QJsonObject & logConfig = config.object(); | ||||
| 		const QJsonObject &logConfig = config.object(); | ||||
|  | ||||
| 		std::string level = logConfig["level"].toString("warn").toStdString(); // silent warn verbose debug | ||||
| 		if (level == "silent")       Logger::setLogLevel(Logger::OFF); | ||||
| 		else if (level == "warn")    Logger::setLogLevel(Logger::WARNING); | ||||
| 		else if (level == "verbose") Logger::setLogLevel(Logger::INFO); | ||||
| 		else if (level == "debug")   Logger::setLogLevel(Logger::DEBUG); | ||||
| 		if (level == "silent") | ||||
| 			Logger::setLogLevel(Logger::OFF); | ||||
| 		else if (level == "warn") | ||||
| 			Logger::setLogLevel(Logger::WARNING); | ||||
| 		else if (level == "verbose") | ||||
| 			Logger::setLogLevel(Logger::INFO); | ||||
| 		else if (level == "debug") | ||||
| 			Logger::setLogLevel(Logger::DEBUG); | ||||
| 	} | ||||
|  | ||||
| 	if(settingsType == settings::SYSTEMCAPTURE) | ||||
| 	if (settingsType == settings::SYSTEMCAPTURE) | ||||
| 	{ | ||||
| 		const QJsonObject & grabberConfig = config.object(); | ||||
| 		const QJsonObject &grabberConfig = config.object(); | ||||
|  | ||||
| 		_grabber_width     = grabberConfig["width"].toInt(96); | ||||
| 		_grabber_height    = grabberConfig["height"].toInt(96); | ||||
| 		_grabber_width = grabberConfig["width"].toInt(96); | ||||
| 		_grabber_height = grabberConfig["height"].toInt(96); | ||||
| 		_grabber_frequency = grabberConfig["frequency_Hz"].toInt(10); | ||||
|  | ||||
| 		_grabber_cropLeft   = grabberConfig["cropLeft"].toInt(0); | ||||
| 		_grabber_cropRight  = grabberConfig["cropRight"].toInt(0); | ||||
| 		_grabber_cropTop    = grabberConfig["cropTop"].toInt(0); | ||||
| 		_grabber_cropLeft = grabberConfig["cropLeft"].toInt(0); | ||||
| 		_grabber_cropRight = grabberConfig["cropRight"].toInt(0); | ||||
| 		_grabber_cropTop = grabberConfig["cropTop"].toInt(0); | ||||
| 		_grabber_cropBottom = grabberConfig["cropBottom"].toInt(0); | ||||
|  | ||||
| 		_grabber_ge2d_mode  = grabberConfig["ge2d_mode"].toInt(0); | ||||
| 		_grabber_device     = grabberConfig["amlogic_grabber"].toString("amvideocap0"); | ||||
| 		_grabber_ge2d_mode = grabberConfig["ge2d_mode"].toInt(0); | ||||
| 		_grabber_device = grabberConfig["amlogic_grabber"].toString("amvideocap0"); | ||||
|  | ||||
| 		#ifdef ENABLE_OSX | ||||
| 			QString type = "osx"; | ||||
| 		#else | ||||
| 			QString type = grabberConfig["type"].toString("auto"); | ||||
| 		#endif | ||||
| #ifdef ENABLE_OSX | ||||
| 		QString type = "osx"; | ||||
| #else | ||||
| 		QString type = grabberConfig["type"].toString("auto"); | ||||
| #endif | ||||
|  | ||||
| 		// auto eval of type | ||||
| 		if ( type == "auto" ) | ||||
| 		if (type == "auto") | ||||
| 		{ | ||||
| 			// dispmanx -> on raspi | ||||
| 			if (QFile::exists("/dev/vchiq")) | ||||
| @@ -302,15 +312,17 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& settingsType, co | ||||
| 				type = "dispmanx"; | ||||
| 			} | ||||
| 			// amlogic -> /dev/amvideo exists | ||||
| 			else if ( QFile::exists("/dev/amvideo") ) | ||||
| 			else if (QFile::exists("/dev/amvideo")) | ||||
| 			{ | ||||
| 				type = "amlogic"; | ||||
|  | ||||
| 					if ( !QFile::exists("/dev/" + _grabber_device) ) | ||||
| 						{ Error( _log, "grabber device '%s' for type amlogic not found!", QSTRING_CSTR(_grabber_device)); } | ||||
| 				if (!QFile::exists("/dev/" + _grabber_device)) | ||||
| 				{ | ||||
| 					Error(_log, "grabber device '%s' for type amlogic not found!", QSTRING_CSTR(_grabber_device)); | ||||
| 				} | ||||
| 			} | ||||
| 			// x11 -> if DISPLAY is set | ||||
| 			else if (getenv("DISPLAY") != NULL ) | ||||
| 			else if (getenv("DISPLAY") != NULL) | ||||
| 			{ | ||||
| 				type = "x11"; | ||||
| 			} | ||||
| @@ -321,9 +333,9 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& settingsType, co | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if(_prevType != type) | ||||
| 		if (_prevType != type) | ||||
| 		{ | ||||
| 			Info(  _log, "set screen capture device to '%s'", QSTRING_CSTR(type)); | ||||
| 			Info(_log, "set screen capture device to '%s'", QSTRING_CSTR(type)); | ||||
|  | ||||
| 			// stop all capture interfaces | ||||
| 			#ifdef ENABLE_FB | ||||
| @@ -376,49 +388,49 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& settingsType, co | ||||
| 			#endif | ||||
|  | ||||
| 			// create/start capture interface | ||||
| 			if(type == "framebuffer") | ||||
| 			if (type == "framebuffer") | ||||
| 			{ | ||||
| 				if(_fbGrabber == nullptr) | ||||
| 				if (_fbGrabber == nullptr) | ||||
| 					createGrabberFramebuffer(grabberConfig); | ||||
| 				#ifdef ENABLE_FB | ||||
| 				_fbGrabber->tryStart(); | ||||
| 				#endif | ||||
| 			} | ||||
| 			else if(type == "dispmanx") | ||||
| 			else if (type == "dispmanx") | ||||
| 			{ | ||||
| 				if(_dispmanx == nullptr) | ||||
| 				if (_dispmanx == nullptr) | ||||
| 					createGrabberDispmanx(); | ||||
| 				#ifdef ENABLE_DISPMANX | ||||
| 				_dispmanx->tryStart(); | ||||
| 				#endif | ||||
| 			} | ||||
| 			else if(type == "amlogic") | ||||
| 			else if (type == "amlogic") | ||||
| 			{ | ||||
| 				if(_amlGrabber == nullptr) | ||||
| 				if (_amlGrabber == nullptr) | ||||
| 					createGrabberAmlogic(); | ||||
| 				#ifdef ENABLE_AMLOGIC | ||||
| 				_amlGrabber->tryStart(); | ||||
| 				#endif | ||||
| 			} | ||||
| 			else if(type == "osx") | ||||
| 			else if (type == "osx") | ||||
| 			{ | ||||
| 				if(_osxGrabber == nullptr) | ||||
| 				if (_osxGrabber == nullptr) | ||||
| 					createGrabberOsx(grabberConfig); | ||||
| 				#ifdef ENABLE_OSX | ||||
| 				_osxGrabber->tryStart(); | ||||
| 				#endif | ||||
| 			} | ||||
| 			else if(type == "x11") | ||||
| 			else if (type == "x11") | ||||
| 			{ | ||||
| 				if(_x11Grabber == nullptr) | ||||
| 				if (_x11Grabber == nullptr) | ||||
| 					createGrabberX11(grabberConfig); | ||||
| 				#ifdef ENABLE_X11 | ||||
| 				_x11Grabber->tryStart(); | ||||
| 				#endif | ||||
| 			} | ||||
| 			else if(type == "qt") | ||||
| 			else if (type == "qt") | ||||
| 			{ | ||||
| 				if(_qtGrabber == nullptr) | ||||
| 				if (_qtGrabber == nullptr) | ||||
| 					createGrabberQt(grabberConfig); | ||||
| 				#ifdef ENABLE_QT | ||||
| 				_qtGrabber->tryStart(); | ||||
| @@ -426,22 +438,22 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& settingsType, co | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				Error(_log,"Unknown platform capture type: %s", QSTRING_CSTR(type)); | ||||
| 				Error(_log, "Unknown platform capture type: %s", QSTRING_CSTR(type)); | ||||
| 				return; | ||||
| 			} | ||||
| 			_prevType = type; | ||||
| 		} | ||||
| 	} | ||||
| 	else if(settingsType == settings::V4L2) | ||||
| 	else if (settingsType == settings::V4L2) | ||||
| 	{ | ||||
|  | ||||
| #ifdef ENABLE_V4L2 | ||||
| 			if(_v4l2Grabber != nullptr) | ||||
| 				return; | ||||
| 		if (_v4l2Grabber != nullptr) | ||||
| 			return; | ||||
|  | ||||
| 			const QJsonObject & grabberConfig = config.object(); | ||||
| 		const QJsonObject &grabberConfig = config.object(); | ||||
|  | ||||
| 			_v4l2Grabber = new V4L2Wrapper( | ||||
| 		_v4l2Grabber = new V4L2Wrapper( | ||||
| 				grabberConfig["device"].toString("auto"), | ||||
| 				grabberConfig["width"].toInt(0), | ||||
| 				grabberConfig["height"].toInt(0), | ||||
| @@ -449,22 +461,23 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& settingsType, co | ||||
| 				parseVideoStandard(grabberConfig["standard"].toString("no-change")), | ||||
| 				parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")), | ||||
| 				grabberConfig["sizeDecimation"].toInt(8)); | ||||
| 			_v4l2Grabber->setSignalThreshold( | ||||
| 				grabberConfig["redSignalThreshold"].toDouble(0.0)/100.0, | ||||
| 				grabberConfig["greenSignalThreshold"].toDouble(0.0)/100.0, | ||||
| 				grabberConfig["blueSignalThreshold"].toDouble(0.0)/100.0); | ||||
| 			_v4l2Grabber->setCropping( | ||||
|  | ||||
| 		_v4l2Grabber->setSignalThreshold( | ||||
| 				grabberConfig["redSignalThreshold"].toDouble(0.0) / 100.0, | ||||
| 				grabberConfig["greenSignalThreshold"].toDouble(0.0) / 100.0, | ||||
| 				grabberConfig["blueSignalThreshold"].toDouble(0.0) / 100.0); | ||||
| 		_v4l2Grabber->setCropping( | ||||
| 				grabberConfig["cropLeft"].toInt(0), | ||||
| 				grabberConfig["cropRight"].toInt(0), | ||||
| 				grabberConfig["cropTop"].toInt(0), | ||||
| 				grabberConfig["cropBottom"].toInt(0)); | ||||
| 			_v4l2Grabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true)); | ||||
| 			_v4l2Grabber->setSignalDetectionOffset( | ||||
| 		_v4l2Grabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true)); | ||||
| 		_v4l2Grabber->setSignalDetectionOffset( | ||||
| 				grabberConfig["sDHOffsetMin"].toDouble(0.25), | ||||
| 				grabberConfig["sDVOffsetMin"].toDouble(0.25), | ||||
| 				grabberConfig["sDHOffsetMax"].toDouble(0.75), | ||||
| 				grabberConfig["sDVOffsetMax"].toDouble(0.75)); | ||||
| 			Debug(_log, "V4L2 grabber created"); | ||||
| 		Debug(_log, "V4L2 grabber created"); | ||||
|  | ||||
| 			// connect to HyperionDaemon signal | ||||
| 			connect(this, &HyperionDaemon::videoMode, _v4l2Grabber, &V4L2Wrapper::setVideoMode); | ||||
| @@ -491,7 +504,6 @@ void HyperionDaemon::createGrabberDispmanx() | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| void HyperionDaemon::createGrabberAmlogic() | ||||
| { | ||||
| #ifdef ENABLE_AMLOGIC | ||||
| @@ -508,13 +520,13 @@ void HyperionDaemon::createGrabberAmlogic() | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void HyperionDaemon::createGrabberX11(const QJsonObject & grabberConfig) | ||||
| void HyperionDaemon::createGrabberX11(const QJsonObject &grabberConfig) | ||||
| { | ||||
| #ifdef ENABLE_X11 | ||||
| 	_x11Grabber = new X11Wrapper( | ||||
| 				_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom, | ||||
| 				grabberConfig["pixelDecimation"].toInt(8), | ||||
| 				_grabber_frequency ); | ||||
| 			_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom, | ||||
| 			grabberConfig["pixelDecimation"].toInt(8), | ||||
| 			_grabber_frequency); | ||||
| 	_x11Grabber->setCropping(_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom); | ||||
|  | ||||
| 	// connect to HyperionDaemon signal | ||||
| @@ -527,14 +539,14 @@ void HyperionDaemon::createGrabberX11(const QJsonObject & grabberConfig) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void HyperionDaemon::createGrabberQt(const QJsonObject & grabberConfig) | ||||
| void HyperionDaemon::createGrabberQt(const QJsonObject &grabberConfig) | ||||
| { | ||||
| #ifdef ENABLE_QT | ||||
| 	_qtGrabber = new QtWrapper( | ||||
| 				_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom, | ||||
| 				grabberConfig["pixelDecimation"].toInt(8), | ||||
| 				grabberConfig["display"].toInt(0), | ||||
| 				_grabber_frequency ); | ||||
| 			_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom, | ||||
| 			grabberConfig["pixelDecimation"].toInt(8), | ||||
| 			grabberConfig["display"].toInt(0), | ||||
| 			_grabber_frequency); | ||||
|  | ||||
| 	// connect to HyperionDaemon signal | ||||
| 	connect(this, &HyperionDaemon::videoMode, _qtGrabber, &QtWrapper::setVideoMode); | ||||
| @@ -546,13 +558,13 @@ void HyperionDaemon::createGrabberQt(const QJsonObject & grabberConfig) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void HyperionDaemon::createGrabberFramebuffer(const QJsonObject & grabberConfig) | ||||
| void HyperionDaemon::createGrabberFramebuffer(const QJsonObject &grabberConfig) | ||||
| { | ||||
| #ifdef ENABLE_FB | ||||
| 	// Construct and start the framebuffer grabber if the configuration is present | ||||
| 	_fbGrabber = new FramebufferWrapper( | ||||
| 				grabberConfig["device"].toString("/dev/fb0"), | ||||
| 				_grabber_width, _grabber_height, _grabber_frequency); | ||||
| 			grabberConfig["device"].toString("/dev/fb0"), | ||||
| 			_grabber_width, _grabber_height, _grabber_frequency); | ||||
| 	_fbGrabber->setCropping(_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom); | ||||
| 	// connect to HyperionDaemon signal | ||||
| 	connect(this, &HyperionDaemon::videoMode, _fbGrabber, &FramebufferWrapper::setVideoMode); | ||||
| @@ -564,14 +576,13 @@ void HyperionDaemon::createGrabberFramebuffer(const QJsonObject & grabberConfig) | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| void HyperionDaemon::createGrabberOsx(const QJsonObject & grabberConfig) | ||||
| void HyperionDaemon::createGrabberOsx(const QJsonObject &grabberConfig) | ||||
| { | ||||
| #ifdef ENABLE_OSX | ||||
| 	// Construct and start the osx grabber if the configuration is present | ||||
| 	_osxGrabber = new OsxWrapper( | ||||
| 				grabberConfig["display"].toInt(0), | ||||
| 				_grabber_width, _grabber_height, _grabber_frequency); | ||||
| 			grabberConfig["display"].toInt(0), | ||||
| 			_grabber_width, _grabber_height, _grabber_frequency); | ||||
|  | ||||
| 	// connect to HyperionDaemon signal | ||||
| 	connect(this, &HyperionDaemon::videoMode, _osxGrabber, &OsxWrapper::setVideoMode); | ||||
|   | ||||
| @@ -1,13 +1,19 @@ | ||||
| #include <cassert> | ||||
| #include <csignal> | ||||
| #include <unistd.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifndef __APPLE__ | ||||
| #if !defined(__APPLE__) && !defined(_WIN32) | ||||
| /* prctl is Linux only */ | ||||
| #include <sys/prctl.h> | ||||
| #endif | ||||
| // getpid() | ||||
| #ifdef _WIN32 | ||||
| #include <process.h> | ||||
| //#include <Windows.h> | ||||
| #else | ||||
| #include <unistd.h> | ||||
| #endif | ||||
|  | ||||
| #include <exception> | ||||
|  | ||||
| @@ -20,7 +26,6 @@ | ||||
| #include <QDir> | ||||
| #include <QStringList> | ||||
| #include <QSystemTrayIcon> | ||||
| #include <QProcess> | ||||
|  | ||||
| #include "HyperionConfig.h" | ||||
|  | ||||
| @@ -30,6 +35,8 @@ | ||||
| #include <commandline/IntOption.h> | ||||
| #include <../../include/db/AuthTable.h> | ||||
|  | ||||
| #include "detectProcess.h" | ||||
|  | ||||
| #ifdef ENABLE_X11 | ||||
| #include <X11/Xlib.h> | ||||
| #endif | ||||
| @@ -41,84 +48,13 @@ using namespace commandline; | ||||
|  | ||||
| #define PERM0664 QFileDevice::ReadOwner | QFileDevice::ReadGroup | QFileDevice::ReadOther | QFileDevice::WriteOwner | QFileDevice::WriteGroup | ||||
|  | ||||
| unsigned int getProcessIdsByProcessName(const char* processName, QStringList &listOfPids) | ||||
| { | ||||
| 	// Clear content of returned list of PIDS | ||||
| 	listOfPids.clear(); | ||||
|  | ||||
| #if defined(WIN32) | ||||
| 	// Get the list of process identifiers. | ||||
| 	DWORD aProcesses[1024], cbNeeded, cProcesses; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) | ||||
| 		return 0; | ||||
|  | ||||
| 	// Calculate how many process identifiers were returned. | ||||
| 	cProcesses = cbNeeded / sizeof(DWORD); | ||||
|  | ||||
| 	// Search for a matching name for each process | ||||
| 	for (i = 0; i < cProcesses; i++) | ||||
| 	{ | ||||
| 		if (aProcesses[i] != 0) | ||||
| 		{ | ||||
| 			char szProcessName[MAX_PATH] = {0}; | ||||
|  | ||||
| 			DWORD processID = aProcesses[i]; | ||||
|  | ||||
| 			// Get a handle to the process. | ||||
| 			HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); | ||||
|  | ||||
| 			// Get the process name | ||||
| 			if (NULL != hProcess) | ||||
| 			{ | ||||
| 				HMODULE hMod; | ||||
| 				DWORD cbNeeded; | ||||
|  | ||||
| 				if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) | ||||
| 					GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(char)); | ||||
|  | ||||
| 				// Release the handle to the process. | ||||
| 				CloseHandle(hProcess); | ||||
|  | ||||
| 				if (*szProcessName != 0 && strcmp(processName, szProcessName) == 0) | ||||
| 					listOfPids.append(QString::number(processID)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return listOfPids.count(); | ||||
|  | ||||
| #else | ||||
|  | ||||
| 	// Run pgrep, which looks through the currently running processses and lists the process IDs | ||||
| 	// which match the selection criteria to stdout. | ||||
| 	QProcess process; | ||||
| 	process.start("pgrep",  QStringList() << processName); | ||||
| 	process.waitForReadyRead(); | ||||
|  | ||||
| 	QByteArray bytes = process.readAllStandardOutput(); | ||||
|  | ||||
| 	process.terminate(); | ||||
| 	process.waitForFinished(); | ||||
| 	process.kill(); | ||||
|  | ||||
| 	// Output is something like "2472\n2323" for multiple instances | ||||
| 	if (bytes.isEmpty()) | ||||
| 		return 0; | ||||
|  | ||||
| 	listOfPids = QString(bytes).split("\n", QString::SkipEmptyParts); | ||||
| 	return listOfPids.count(); | ||||
|  | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| void signal_handler(const int signum) | ||||
| { | ||||
| 	// Hyperion Managment instance | ||||
| 	HyperionIManager* _hyperion = HyperionIManager::getInstance(); | ||||
| 	HyperionIManager *_hyperion = HyperionIManager::getInstance(); | ||||
|  | ||||
| 	if(signum == SIGCHLD) | ||||
| 	if (signum == SIGCHLD) | ||||
| 	{ | ||||
| 		// only quit when a registered child process is gone | ||||
| 		// currently this feature is not active ... | ||||
| @@ -146,6 +82,7 @@ void signal_handler(const int signum) | ||||
| 	// reset signal handler to default (in case this handler is not capable of stopping) | ||||
| 	signal(signum, SIG_DFL); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| QCoreApplication* createApplication(int &argc, char *argv[]) | ||||
| { | ||||
| @@ -166,7 +103,7 @@ QCoreApplication* createApplication(int &argc, char *argv[]) | ||||
| 	} | ||||
|  | ||||
| 	// on osx/windows gui always available | ||||
| #if defined(__APPLE__) || defined(__WIN32__) | ||||
| #if defined(__APPLE__) || defined(_WIN32) | ||||
| 	isGuiApp = true && ! forceNoGui; | ||||
| #else | ||||
| 	if (!forceNoGui) | ||||
| @@ -204,10 +141,15 @@ QCoreApplication* createApplication(int &argc, char *argv[]) | ||||
|  | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
| #ifndef _WIN32 | ||||
| 	setenv("AVAHI_COMPAT_NOWARN", "1", 1); | ||||
|  | ||||
| #endif | ||||
| #ifdef _WIN32 | ||||
| 	// We can get a console window also in app gui mode conditional | ||||
| 	//AllocConsole(); | ||||
| #endif | ||||
| 	// initialize main logger and set global log level | ||||
| 	Logger* log = Logger::getInstance("MAIN"); | ||||
| 	Logger *log = Logger::getInstance("MAIN"); | ||||
| 	Logger::setLogLevel(Logger::WARNING); | ||||
|  | ||||
| 	// check if we are running already an instance | ||||
| @@ -215,7 +157,12 @@ int main(int argc, char** argv) | ||||
| 	// TODO Allow one session per user | ||||
| 	// http://www.qtcentre.org/threads/44489-Get-Process-ID-for-a-running-application | ||||
| 	QStringList listOfPids; | ||||
| 	if(getProcessIdsByProcessName("hyperiond", listOfPids) > 1) | ||||
| 	#ifdef _WIN32 | ||||
| 		const char* processName = "hyperiond.exe"; | ||||
| 	#else | ||||
| 		const char* processName = "hyperiond"; | ||||
| 	#endif | ||||
| 	if (getProcessIdsByProcessName(processName, listOfPids) > 1) | ||||
| 	{ | ||||
| 		Error(log, "The Hyperion Daemon is already running, abort start"); | ||||
| 		return 0; | ||||
| @@ -226,6 +173,7 @@ int main(int argc, char** argv) | ||||
|  | ||||
| 	bool isGuiApp = (qobject_cast<QApplication *>(app.data()) != 0 && QSystemTrayIcon::isSystemTrayAvailable()); | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| 	signal(SIGINT,  signal_handler); | ||||
| 	signal(SIGTERM, signal_handler); | ||||
| 	signal(SIGABRT, signal_handler); | ||||
| @@ -233,7 +181,7 @@ int main(int argc, char** argv) | ||||
| 	signal(SIGPIPE, signal_handler); | ||||
| 	signal(SIGUSR1, signal_handler); | ||||
| 	signal(SIGUSR2, signal_handler); | ||||
|  | ||||
| #endif | ||||
| 	// force the locale | ||||
| 	setlocale(LC_ALL, "C"); | ||||
| 	QLocale::setDefault(QLocale::c()); | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
|  | ||||
| #include <list> | ||||
| #ifndef _WIN32 | ||||
| #include <unistd.h> | ||||
|  | ||||
| #endif | ||||
| #include <QPixmap> | ||||
| #include <QWindow> | ||||
| #include <QGuiApplication> | ||||
| @@ -126,6 +127,7 @@ void SysTray::closeEvent(QCloseEvent *event) | ||||
|  | ||||
| void SysTray::settings() | ||||
| { | ||||
| #ifndef _WIN32 | ||||
| 	// Hide error messages when opening webbrowser | ||||
|  | ||||
| 	int out_pipe[2]; | ||||
| @@ -144,13 +146,16 @@ void SysTray::settings() | ||||
| 		// redirecting stderr to stdout | ||||
| 		::dup2(STDOUT_FILENO, STDERR_FILENO); | ||||
| 	} | ||||
| 	#endif | ||||
|  | ||||
| 	QDesktopServices::openUrl(QUrl("http://localhost:"+QString::number(_webPort)+"/", QUrl::TolerantMode)); | ||||
|  | ||||
| 	 | ||||
| 	#ifndef _WIN32 | ||||
| 	// restoring stdout | ||||
| 	::dup2(saved_stdout, STDOUT_FILENO); | ||||
| 	// restoring stderr | ||||
| 	::dup2(saved_stderr, STDERR_FILENO); | ||||
| 	#endif | ||||
| } | ||||
|  | ||||
| void SysTray::setEffect() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user