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
69 changed files with 3184 additions and 871 deletions

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