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:
brindosch 2020-05-12 19:51:19 +02:00 committed by GitHub
parent 598b404f38
commit 510bb903ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
69 changed files with 3184 additions and 871 deletions

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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 ###
######################

View File

@ -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 ###
######################

View File

@ -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
View 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
View 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
View 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"
}
]
}

View File

@ -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()

View File

@ -3,10 +3,7 @@ You can participate in the translation.
[![Join Translation](https://img.shields.io/badge/POEditor-translate-green.svg)](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

View File

@ -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``

View File

@ -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

View File

@ -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!
[![Hyperion webpage/forum](https://img.shields.io/website/https/hyperion-project.org.svg?down_color=red&down_message=offline&up_color=green&up_message=online)](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.
[![Contributors](https://img.shields.io/github/contributors/hyperion-project/hyperion.ng.svg)](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.
[![Join Translation](https://img.shields.io/badge/POEditor-translate-green.svg)](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).
[![GitHub license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/LICENSE)

View File

@ -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
View 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
View 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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

1
cmake/nsis/icon.rc Normal file
View File

@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "installer.ico"

BIN
cmake/nsis/installer.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View 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

View 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

View File

@ -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()

View File

@ -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)

View File

@ -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`).

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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);
};

View File

@ -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()

View File

@ -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())

View File

@ -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;

View File

@ -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()

View File

@ -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;
}

View File

@ -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 ()

View File

@ -2,7 +2,6 @@
// STL includes
#include <exception>
#include <sstream>
#include <unistd.h>
// QT includes
#include <QString>

View File

@ -1,6 +1,5 @@
// STL includes
#include <cstring>
#include <unistd.h>
#include <iostream>
// hyperion includes

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -1,4 +1,9 @@
#ifdef _WIN32
#include <winsock.h>
#else
#include <arpa/inet.h>
#endif
#include <QHostInfo>
// hyperion local includes

View File

@ -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 ];

View File

@ -1,4 +1,9 @@
#ifdef _WIN32
#include <winsock.h>
#else
#include <arpa/inet.h>
#endif
#include <QHostInfo>
// hyperion local includes

View File

@ -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;

View File

@ -6,7 +6,6 @@
#include <exception>
// Linux includes
#include <fcntl.h>
#include <sys/ioctl.h>
#include <QStringList>
#include <QUdpSocket>

View File

@ -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

View File

@ -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()

View File

@ -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");

View File

@ -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;
}
}

View File

@ -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

View File

@ -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];

View File

@ -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());
}

View File

@ -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);
}

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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 ()

View 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
}

View File

@ -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);

View File

@ -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());

View File

@ -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()