Qt6 support (#1363)

* Initial Qt6 config

* Change Package order to reingfence missing packages

* Update to QT 6.2.0

* Qt 6.2.0 updates

* macOS fix

* Simplify handling QT5 & Qt6 in parallel

* Updates for Windows

* Fix macos build

* macOS linker fix

* General support of QTDIR, update docu

* MaxOS add default qt directories

* Fix merge typo

* Update default CMakeSettings.json with installation path options

* Add additional libs required by Qt6 to CompileHowTo

* Fix Qt5 items

Co-authored-by: Paulchen-Panther <16664240+Paulchen-Panther@users.noreply.github.com>
This commit is contained in:
LordGrey 2021-11-16 17:12:56 +00:00 committed by GitHub
parent 3b1ca20b10
commit 25d79a9f3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 645 additions and 541 deletions

View File

@ -124,9 +124,9 @@ if ( "${PLATFORM}" MATCHES "osx" )
# specify the min version of the target platform
SET ( CMAKE_OSX_DEPLOYMENT_TARGET "10.15" )
# add specific prefix paths
FIRSTSUBDIR(SUBDIRQT "/usr/local/Cellar/qt")
FIRSTSUBDIR(SUBDIRPY "/usr/local/opt/python3/Frameworks/Python.framework/Versions")
SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${SUBDIRQT} ${SUBDIRPY} "/usr/local/opt/qt5" )
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${SUBDIRPY})
include_directories("/opt/X11/include/")
SET ( DEFAULT_OSX ON )
SET ( DEFAULT_USB_HID ON )
@ -299,26 +299,6 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
# Prefer static linking over dynamic
#set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so")
# 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")
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()
# MSVC options
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# Search for Windows SDK
@ -326,44 +306,6 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
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
#
# Alternatively, use Qt5_BASE_DIR environment variable to point to Qt version to be used
# In MSVC19 add into CMakeSettings.json
#
# "environments": [
# {
# "Qt5_BASE_DIR": "D:/Qt/5.15.1/msvc2019_64"
# }
# ]
if (NOT DEFINED ENV{Qt5_BASE_DIR})
FIRSTSUBDIR(SUBDIRQT "C:/Qt")
SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${SUBDIRQT}/msvc2019_64")
else()
message(STATUS "Qt5_BASE_DIR: $ENV{Qt5_BASE_DIR}")
message(STATUS "Add Qt5_BASE_DIR: $ENV{Qt5_BASE_DIR} to CMAKE_PREFIX_PATH")
SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "$ENV{Qt5_BASE_DIR}")
endif()
if (NOT DEFINED ENV{Qt5_DIR})
if (NOT DEFINED ENV{Qt5_BASE_DIR})
SET (qt_module_path "${SUBDIRQT}/msvc2019_64/lib/cmake/Qt5")
else ()
SET (qt_module_path "$ENV{Qt5_BASE_DIR}/lib/cmake/Qt5")
endif()
else()
SET (qt_module_path "$ENV{Qt5_DIR}")
endif()
message(STATUS "Add ${qt_module_path} to CMAKE_MODULE_PATH")
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${qt_module_path}")
#message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
#message(STATUS "CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")
# Search for DirectX9
if (ENABLE_DX)
find_package(DirectX9 REQUIRED)
@ -372,60 +314,80 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
endif()
# Use GNU gold linker if available
if (NOT WIN32)
if (NOT WIN32 AND NOT APPLE)
include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/LDGold.cmake)
endif()
if (ENABLE_DEPLOY_DEPENDENCIES)
# Don't create new dynamic tags (RUNPATH)
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# Don't create new dynamic tags (RUNPATH) and setup -rpath to search for shared libs in BINARY/../lib folder (only for Unix)
if (ENABLE_DEPLOY_DEPENDENCIES AND UNIX AND NOT APPLE)
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)
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN/../lib")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif ()
endif ()
# add QT5 dependency
IF ( CMAKE_CROSSCOMPILING )
file(GLOB QT_BIN ${QT_BIN_PATH})
set(QT_MOC_EXECUTABLE ${QT_BIN}/moc)
add_executable(Qt5::moc IMPORTED)
set_property(TARGET Qt5::moc PROPERTY IMPORTED_LOCATION ${QT_MOC_EXECUTABLE})
set(QT_RCC_EXECUTABLE ${QT_BIN}/rcc)
add_executable(Qt5::rcc IMPORTED)
set_property(TARGET Qt5::rcc PROPERTY IMPORTED_LOCATION ${QT_RCC_EXECUTABLE})
message(STATUS "QT_BIN_PATH = ${QT_BIN}")
message(STATUS "QT_MOC_EXECUTABLE = ${QT_MOC_EXECUTABLE}")
message(STATUS "QT_RCC_EXECUTABLE = ${QT_RCC_EXECUTABLE}")
ENDIF()
SET(QT_MIN_VERSION "5.5.0")
find_package(Qt5 COMPONENTS Core Gui Network SerialPort Sql REQUIRED)
message( STATUS "Found Qt Version: ${Qt5Core_VERSION}" )
IF ( "${Qt5Core_VERSION}" VERSION_LESS "${QT_MIN_VERSION}" )
message( FATAL_ERROR "Your Qt version is to old! Minimum required ${QT_MIN_VERSION}" )
ENDIF()
# Add libusb and pthreads
find_package(libusb-1.0 REQUIRED)
find_package(Threads REQUIRED)
add_definitions(${QT_DEFINITIONS})
if(APPLE)
set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics")
endif()
find_package(Threads REQUIRED)
# Allow to overwrite QT base directory
# Either supply QTDIR as -DQTDIR=<path> to cmake or set and environment variable QTDIR pointing to the Qt installation
# For Windows and OSX, the default Qt installation path are tried to resolved automatically
if (NOT DEFINED QTDIR)
if (DEFINED ENV{QTDIR})
set(QTDIR $ENV{QTDIR})
else()
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
FIRSTSUBDIR(SUBDIRQT "C:/Qt")
if (NOT ${SUBDIRQT} STREQUAL "")
set(QTDIR "${SUBDIRQT}/msvc2019_64")
endif()
elseif ( "${PLATFORM}" MATCHES "osx" )
if (EXISTS /usr/local/opt/qt6)
set(QTDIR "/usr/local/opt/qt6")
elseif (EXISTS /usr/local/opt/qt5)
set(QTDIR "/usr/local/opt/qt5")
endif()
endif()
endif()
endif()
if (DEFINED QTDIR)
message(STATUS "Add QTDIR: ${QTDIR} to CMAKE_PREFIX_PATH")
list(PREPEND CMAKE_PREFIX_PATH ${QTDIR} "${QTDIR}/lib")
endif()
message( STATUS "CMAKE_PREFIX_PATH used: ${CMAKE_PREFIX_PATH}" )
# find QT libs
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network SerialPort Sql Widgets REQUIRED)
message( STATUS "Found Qt Version: ${QT_VERSION}" )
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6 )
SET(QT_MIN_VERSION "6.2.0")
ELSE()
SET(QT_MIN_VERSION "5.5.0")
ENDIF()
IF ( "${QT_VERSION}" VERSION_LESS "${QT_MIN_VERSION}" )
message( FATAL_ERROR "Your Qt version is to old! Minimum required ${QT_MIN_VERSION}" )
ENDIF()
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network SerialPort Sql Widgets REQUIRED)
message( STATUS "Qt version used: ${QT_VERSION}" )
if (APPLE AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6) )
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl)
ENDIF()
# Add libusb and pthreads
find_package(libusb-1.0 REQUIRED)
add_definitions(${QT_DEFINITIONS})
# Add the source/lib directories
add_subdirectory(dependencies)
add_subdirectory(libsrc)
@ -445,6 +407,33 @@ LIST( APPEND GENERATED_QRC
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${GENERATED_QRC}" )
# 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)
if(APPLE)
CHECK_CXX_COMPILER_FLAG("Werror=unguarded-availability" REQUIRED_UNGUARDED_AVAILABILITY)
if(REQUIRED_UNGUARDED_AVAILABILITY)
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "Werror=unguarded-availability")
endif()
endif()
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()
# uninstall target
configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)

46
CMakeSettings.json Normal file
View File

@ -0,0 +1,46 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\build-${name}",
"installRoot": "${projectDir}\\install-${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"variables": [
// Replace path with your TurboJPEG installation path
//{ "name": "TurboJPEG_INCLUDE_DIRS", "type": "PATH", "value": "YourTurboJPEGPath/libjpeg-turbo64/include" },
//{ "name": "TurboJPEG_LIBRARY", "value": "YourTurboJPEGPath/libjpeg-turbo64/lib/turbojpeg.lib", "type": "FILEPATH" }
],
"environments": [
// Replace path with your installation path
//{ "QTDIR": "C:/Qt/6.2.0/msvc2019_64/" },
//{ "VULKAN_SDK": "C:/VulkanSDK/1.2.182.0" }
]
},
{
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "Release",
"buildRoot": "${projectDir}\\build-${name}",
"installRoot": "${projectDir}\\install-${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "package",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": [
// Replace path with your TurboJPEG installation path
//{ "name": "TurboJPEG_INCLUDE_DIRS", "type": "PATH", "value": "YourTurboJPEGPath/libjpeg-turbo64/include" },
//{ "name": "TurboJPEG_LIBRARY", "value": "YourTurboJPEGPath/libjpeg-turbo64/lib/turbojpeg.lib", "type": "FILEPATH" }
],
"environments": [
// Replace path with your installation path
//{ "QTDIR": "C:/Qt/6.2.0/msvc2019_64/" },
//{ "VULKAN_SDK": "C:/VulkanSDK/1.2.182.0" }
]
}
]
}

View File

@ -27,6 +27,9 @@ make_release()
bin/create_release.sh . ${RELEASE}
}
#export QTDIR="/opt/Qt/6.2.0/gcc_64"
#export QTDIR=="/opt/Qt/5.15.2/gcc_64"
CMAKE_PROTOC_FLAG="-DIMPORT_PROTOC=../build-x86x64/protoc_export.cmake"
CMAKE_FLATC_FLAG="-DIMPORT_FLATC=../build-x86x64/flatc_export.cmake"

View File

@ -2,7 +2,7 @@ macro(DeployMacOS TARGET)
if (EXISTS ${TARGET_FILE})
message(STATUS "Collecting Dependencies for target file: ${TARGET_FILE}")
get_target_property(QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
get_target_property(QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
execute_process(
COMMAND ${QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS
OUTPUT_VARIABLE QT_PLUGIN_DIR
@ -121,10 +121,6 @@ macro(DeployLinux TARGET)
list(APPEND SYSTEM_LIBS_SKIP "libcec")
endif()
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 "" "")
@ -133,6 +129,7 @@ macro(DeployLinux TARGET)
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()
@ -170,22 +167,23 @@ macro(DeployLinux TARGET)
endforeach()
endif(OPENSSL_FOUND)
# Detect the Qt5 plugin directory
get_target_property(QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
# Detect the Qt plugin directory, source: https://github.com/lxde/lxqt-qtplugin/blob/master/src/CMakeLists.txt
if ( TARGET Qt${QT_VERSION_MAJOR}::qmake )
get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
execute_process(
COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS
OUTPUT_VARIABLE QT_PLUGINS_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
# 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}/*")
file(GLOB files "${QT_PLUGINS_DIR}/${PLUGIN}/*.so")
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)
@ -273,17 +271,21 @@ endmacro()
macro(DeployWindows TARGET)
if (EXISTS ${TARGET_FILE})
message(STATUS "Collecting Dependencies for target file: ${TARGET_FILE}")
find_package(Qt5Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR}Core REQUIRED)
find_package(OpenSSL REQUIRED)
# Find the windeployqt binaries
get_target_property(QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
get_target_property(QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::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)
if (QT_VERSION_MAJOR EQUAL 5)
set(WINDEPLOYQT_PARAMS --no-angle --no-opengl-sw)
else()
set(WINDEPLOYQT_PARAMS --no-opengl-sw)
endif()
execute_process(
COMMAND "${CMAKE_COMMAND}" -E

View File

@ -77,6 +77,12 @@ if (USE_SYSTEM_PROTO_LIBS)
find_package(Protobuf REQUIRED)
else ()
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library")
set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "Build protobuf shared")
if (WIN32)
set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Build protobuf static")
endif()
add_subdirectory(external/protobuf)
if(CMAKE_CROSSCOMPILING)
@ -94,6 +100,8 @@ else ()
# define the protoc executable at the parent scope
get_property(PROTOBUF_PROTOC_EXECUTABLE TARGET protoc_compiler PROPERTY LOCATION)
endif()
option(protobuf_BUILD_TESTS "" OFF)
set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} PARENT_SCOPE)
set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE)
include_directories(${PROTOBUF_INCLUDE_DIRS})

View File

@ -58,7 +58,19 @@ cd $HYPERION_HOME
```console
sudo apt-get update
sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5x11extras5-dev libusb-1.0-0-dev python3-dev libcec-dev libxcb-image0-dev libxcb-util0-dev libxcb-shm0-dev libxcb-render0-dev libxcb-randr0-dev libxrandr-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libturbojpeg0-dev libssl-dev zlib1g-dev
sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5x11extras5-dev libusb-1.0-0-dev python3-dev libavahi-core-dev libavahi-compat-libdnssd-dev libturbojpeg0-dev libssl-dev zlib1g-dev
```
**For Linux X11/XXCB grabber support**
```console
sudo apt-get install libxrandr-dev libxrender-dev libxcb-image0-dev libxcb-util0-dev libxcb-shm0-dev libxcb-render0-dev libxcb-randr0-dev
```
**For Linux CEC support**
```console
sudo apt-get install libcec-dev libp8-platform-dev libudev-dev
```
**on RPI you need the videocore IV headers**
@ -72,6 +84,11 @@ sudo apt-get install libraspberrypi-dev
sudo apt-get install rbp-userland-dev-osmc
```
**Additionally for QT6**
```console
sudo apt-get install postgresql unixodbc libxkbcommon-dev
```
**ATTENTION Win10LinuxSubsystem** we do not (/we can't) support using hyperion in linux subsystem of MS Windows 10, albeit some users tested it with success. Keep in mind to disable
all linux specific led and grabber hardware via cmake. Because we use QT as framework in hyperion, serialport leds and network driven devices could work.
@ -95,7 +112,7 @@ First you need to install the dependencies:
brew install qt5 python3 cmake libusb doxygen zlib
```
## Windows (WIP)
## Windows
We assume a 64bit Windows 10. Install the following;
- [Git](https://git-scm.com/downloads) (Check: Add to PATH)
- [CMake (Windows win64-x64 installer)](https://cmake.org/download/) (Check: Add to PATH)
@ -106,6 +123,7 @@ We assume a 64bit Windows 10. Install the following;
- [Python 3 (Windows x86-64 executable installer)](https://www.python.org/downloads/windows/) (Check: Add to PATH and Debug Symbols)
- Open a console window and execute `pip install aqtinstall`.
- Now we can download Qt to _C:\Qt_ `mkdir c:\Qt && aqt install -O c:\Qt 5.15.0 windows desktop win64_msvc2019_64`
- QT6.2 requires the [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) to be installed
- [libjpeg-turbo SDK for Visual C++](https://sourceforge.net/projects/libjpeg-turbo/files/)
- Download the latest 64bit installer (currently `libjpeg-turbo-2.1.0-vc64.exe`) and install to its default location `C:\libjpeg-turbo64`.
@ -145,6 +163,21 @@ bin/hyperiond
# webui is located on localhost:8090 or 8091
```
In case you would like to build with a dedicated Qt version, Either supply ``QTDIR`` as ``-DQTDIR=<path>`` to cmake or set and environment variable ``QTDIR`` pointing to the Qt installation.
On Windows MSVC2019 set it via the CMakeSettings.json:
```posh
"configurations": [
{
...
"environments": [
{
"QTDIR": "C:/Qt/6.2.0/msvc2019_64/"
}
]
},
```
## The detailed way (with many comments)
**Download:**
@ -186,11 +219,6 @@ Platform should be auto detected and refer to osx, you can also force osx:
cmake -DPLATFORM=osx -DCMAKE_BUILD_TYPE=Release ..
```
In case you would like to build with a dedicated Qt version, provide the version's location via the CMAKE_PREFIX_PATH:
```console
cmake -DCMAKE_PREFIX_PATH=/opt/Qt/5.15.2/gcc_64 -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:
@ -233,6 +261,3 @@ cmake -DCMAKE_INSTALL_PREFIX=/home/pi/apps ..
This will install to ``/home/pi/apps/share/hyperion``
**Integrating hyperion into your system:**
... ToDo

View File

@ -29,8 +29,8 @@ struct EffectCmdData
struct registerData
{
const hyperion::Components component;
const QString origin;
const QString owner;
const hyperion::Components callerComp;
hyperion::Components component;
QString origin;
QString owner;
hyperion::Components callerComp;
};

View File

@ -127,7 +127,7 @@ namespace hyperion
// only test the topleft third of the image
int width = image.width() /3;
int height = image.height() / 3;
int maxSize = std::max(width, height);
int maxSize = qMax(width, height);
int firstNonBlackXPixelIndex = -1;
int firstNonBlackYPixelIndex = -1;
@ -135,8 +135,8 @@ namespace hyperion
// find some pixel of the image
for (int i = 0; i < maxSize; ++i)
{
int x = std::min(i, width);
int y = std::min(i, height);
int x = qMin(i, width);
int y = qMin(i, height);
const Pixel_T & color = image(x, y);
if (!isBlack(color))

View File

@ -55,7 +55,7 @@ public:
int minValue = 0;
int maxValue = 0;
int step = 0;
int default = 0;
int def = 0;
int currentValue = 0;
};

View File

@ -79,7 +79,11 @@ public:
QJsonObject discover(const QJsonObject& params);
protected:
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool nativeEventFilter(const QByteArray & eventType, void * message, qintptr * result) override;
#else
bool nativeEventFilter(const QByteArray & eventType, void * message, long int * result) override;
#endif
private:

View File

@ -49,7 +49,11 @@ public:
QJsonObject discover(const QJsonObject& params);
private:
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool nativeEventFilter(const QByteArray & eventType, void * message, qintptr * result) override;
#else
bool nativeEventFilter(const QByteArray & eventType, void * message, long int * result) override;
#endif
void freeResources();
void setupResources();
void setupRender();

View File

@ -6,7 +6,11 @@
#include <utils/ColorRgb.h>
#include <utils/Components.h>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#include <QRecursiveMutex>
#else
#include <QMutex>
#endif
class LedDevice;
class Hyperion;
@ -124,8 +128,12 @@ private slots:
protected:
/// contains all available led device constructors
static LedDeviceRegistry _ledDeviceMap;
static QMutex _ledDeviceMapLock;
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
static QRecursiveMutex _ledDeviceMapLock;
#else
static QMutex _ledDeviceMapLock;
#endif
private:
///
/// @brief switchOff() the device and Stops the device thread

View File

@ -2,7 +2,9 @@
#include <ssdp/SSDPServer.h>
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
#include <QNetworkConfiguration>
#endif
// utils
#include <utils/settings.h>
@ -89,12 +91,16 @@ private slots:
/// @brief Handle changes in the network configuration
/// @param conig New config
///
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
void handleNetworkConfigurationChanged(const QNetworkConfiguration &config);
#endif
private:
WebServer* _webserver;
QString _localAddress;
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QNetworkConfigurationManager* _NCA;
#endif
QString _uuid;
/// Targets for announcement
std::vector<QString> _deviceList;

View File

@ -6,7 +6,12 @@
#include <QMap>
#include <QAtomicInteger>
#include <QList>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#include <QRecursiveMutex>
#else
#include <QMutex>
#endif
// stl includes
#include <stdio.h>
@ -81,7 +86,11 @@ protected:
private:
void write(const Logger::T_LOG_MESSAGE & message);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
static QRecursiveMutex MapLock;
#else
static QMutex MapLock;
#endif
static QMap<QString,Logger*> LoggerMap;
static QAtomicInteger<int> GLOBAL_MIN_LOG_LEVEL;

View File

@ -3,9 +3,15 @@
#include <QString>
#include <QStringList>
#include <QStringRef>
#include <QVector>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#include <QStringView>
#else
#include <QStringRef>
#endif
namespace QStringUtils {
enum class SplitBehavior {
@ -31,42 +37,6 @@ inline QStringList split (const QString &string, QChar sep, SplitBehavior behavi
#endif
}
inline QStringList split (const QString &string, const QRegExp &rx, SplitBehavior behavior = SplitBehavior::KeepEmptyParts)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
return behavior == SplitBehavior::SkipEmptyParts ? string.split(rx, Qt::SkipEmptyParts) : string.split(rx, Qt::KeepEmptyParts);
#else
return behavior == SplitBehavior::SkipEmptyParts ? string.split(rx, QString::SkipEmptyParts) : string.split(rx, QString::KeepEmptyParts);
#endif
}
inline QVector<QStringRef> splitRef(const QString &string, const QString &sep, SplitBehavior behavior = SplitBehavior::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
return string.splitRef(sep, behavior == SplitBehavior::SkipEmptyParts ? Qt::SkipEmptyParts : Qt::KeepEmptyParts , cs);
#else
return string.splitRef(sep, behavior == SplitBehavior::SkipEmptyParts ? QString::SkipEmptyParts : QString::KeepEmptyParts, cs);
#endif
}
inline QVector<QStringRef> splitRef(const QString &string, QChar sep, SplitBehavior behavior = SplitBehavior::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
return string.splitRef(sep, behavior == SplitBehavior::SkipEmptyParts ? Qt::SkipEmptyParts : Qt::KeepEmptyParts, cs);
#else
return string.splitRef(sep, behavior == SplitBehavior::SkipEmptyParts ? QString::SkipEmptyParts : QString::KeepEmptyParts, cs);
#endif
}
inline QVector<QStringRef> splitRef(const QString &string, const QRegExp &rx, SplitBehavior behavior = SplitBehavior::KeepEmptyParts)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
return string.splitRef(rx,behavior == SplitBehavior::SkipEmptyParts ? Qt::SkipEmptyParts : Qt::KeepEmptyParts);
#else
return string.splitRef(rx, behavior == SplitBehavior::SkipEmptyParts ? QString::SkipEmptyParts : QString::KeepEmptyParts);
#endif
}
}
#endif // QSTRINGUTILS_H

View File

@ -5,6 +5,8 @@
#include <hyperion/ColorAdjustment.h>
#include <hyperion/MultiColorAdjustment.h>
#include <hyperion/LedString.h>
#include <QRegularExpression>
// fg effect
#include <hyperion/Hyperion.h>
#include <hyperion/PriorityMuxer.h>
@ -107,7 +109,7 @@ namespace hyperion {
MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt);
const QJsonValue adjustmentConfig = colorConfig["channelAdjustment"];
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
const QRegularExpression overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
const QJsonArray & adjustmentConfigArray = adjustmentConfig.toArray();
for (signed i = 0; i < adjustmentConfigArray.size(); ++i)
@ -125,7 +127,7 @@ namespace hyperion {
continue;
}
if (!overallExp.exactMatch(ledIndicesStr))
if (!overallExp.match(ledIndicesStr).hasMatch())
{
//Error(Logger::getInstance("HYPERION"), "Given led indices %d not correct format: %s", i, QSTRING_CSTR(ledIndicesStr));
continue;

View File

@ -97,6 +97,8 @@ private:
///
void checkProperties(const QJsonObject& value, const QJsonObject& schema);
bool verifyDeps(const QString& property, const QJsonObject& value, const QJsonObject& schema);
///
/// Checks whether certain properties of a JSON object exist under certain dependencies and are the same.
/// If this is not the case _error is set to true and an error-message is added
@ -197,14 +199,6 @@ private:
///
void checkEnum(const QJsonValue& value, const QJsonValue& schema, const QJsonValue& defaultValue);
///
/// @brief Return the "default" value as string. If not found, an empty string is output
///
/// @param value The JSON value to search
/// @return The "default" value as string
///
QString getDefaultValue(const QJsonValue & value);
private:
/// The schema of the entire json-configuration
QJsonObject _qSchema;

View File

@ -29,7 +29,7 @@ endif(ENABLE_DX)
target_link_libraries(hyperion-api
hyperion
hyperion-utils
Qt5::Core
Qt5::Gui
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
)

View File

@ -128,8 +128,8 @@ void BoblightClientConnection::socketClosed()
void BoblightClientConnection::handleMessage(const QString& message)
{
//std::cout << "boblight message: " << message.toStdString() << std::endl;
const QVector<QStringRef> messageParts = QStringUtils::splitRef(message, ' ', QStringUtils::SplitBehavior::SkipEmptyParts);
if (messageParts.size() > 0)
QStringList messageParts = QStringUtils::split(message, ' ', QStringUtils::SplitBehavior::SkipEmptyParts);
if (!messageParts.isEmpty())
{
if (messageParts[0] == "hello")
{
@ -259,7 +259,7 @@ const float ipows[] = {
1.0f / 10000000.0f,
1.0f / 100000000.0f };
float BoblightClientConnection::parseFloat(const QStringRef& s, bool* ok) const
float BoblightClientConnection::parseFloat(const QString& s, bool *ok) const
{
// We parse radix 10
const char MIN_DIGIT = '0';
@ -340,7 +340,7 @@ float BoblightClientConnection::parseFloat(const QStringRef& s, bool* ok) const
return f;
}
unsigned BoblightClientConnection::parseUInt(const QStringRef& s, bool* ok) const
unsigned BoblightClientConnection::parseUInt(const QString& s, bool *ok) const
{
// We parse radix 10
const char MIN_DIGIT = '0';
@ -372,7 +372,7 @@ unsigned BoblightClientConnection::parseUInt(const QStringRef& s, bool* ok) cons
return n;
}
uint8_t BoblightClientConnection::parseByte(const QStringRef& s, bool* ok) const
uint8_t BoblightClientConnection::parseByte(const QString& s, bool *ok) const
{
const int LO = 0;
const int HI = 255;

View File

@ -81,7 +81,7 @@ private:
/// @param ok whether the result is ok
/// @return the parsed byte value in range 0 to 255, or 0
///
uint8_t parseByte(const QStringRef& s, bool *ok = nullptr) const;
uint8_t parseByte(const QString& s, bool *ok = nullptr) const;
///
/// Parse the given QString as unsigned int value.
@ -90,7 +90,7 @@ private:
/// @param ok whether the result is ok
/// @return the parsed unsigned int value
///
unsigned parseUInt(const QStringRef& s, bool *ok = nullptr) const;
unsigned parseUInt(const QString& s, bool *ok = nullptr) const;
///
/// Parse the given QString as float value, e.g. the 16-bit (wide char) QString "1" shall represent 1, "0.5" is 0.5 and so on.
@ -99,7 +99,7 @@ private:
/// @param ok whether the result is ok
/// @return the parsed float value, or 0
///
float parseFloat(const QStringRef& s, bool *ok = nullptr) const;
float parseFloat(const QString& s, bool *ok = nullptr) const;
///
/// Read an incoming boblight message as QString

View File

@ -10,7 +10,7 @@ add_library(bonjour ${Bonjour_SOURCES} )
target_link_libraries(bonjour
hyperion
hyperion-utils
Qt5::Network
Qt${QT_VERSION_MAJOR}::Network
)
IF (NOT APPLE)

View File

@ -12,6 +12,6 @@ include_directories(${CEC_INCLUDE_DIRS})
target_link_libraries(cechandler
dl
${CEC_LIBRARIES}
Qt5::Core
Qt${QT_VERSION_MAJOR}::Core
)

View File

@ -8,5 +8,5 @@ add_library(commandline ${Parser_SOURCES} )
target_link_libraries(commandline
hyperion
Qt5::Gui
Qt${QT_VERSION_MAJOR}::Gui
)

View File

@ -1,5 +1,3 @@
find_package(Qt5 COMPONENTS Sql REQUIRED)
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/db)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/db)
@ -13,6 +11,6 @@ add_library(database
target_link_libraries(database
hyperion
hyperion-utils
Qt5::Core
Qt5::Sql
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Sql
)

View File

@ -422,7 +422,7 @@ void DBManager::doAddBindValue(QSqlQuery& query, const QVariantList& variants) c
{
for(const auto& variant : variants)
{
QVariant::Type t = variant.type();
auto t = variant.userType();
switch(t)
{
case QVariant::UInt:

View File

@ -36,8 +36,8 @@ add_library(effectengine
target_link_libraries(effectengine
hyperion
python
Qt5::Core
Qt5::Gui
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
)
if (NOT CMAKE_VERSION VERSION_LESS "3.12")

View File

@ -10,28 +10,6 @@
#include <QMap>
#include <QByteArray>
// createEffect helper
struct find_schema : std::unary_function<EffectSchema, bool>
{
QString pyFile;
find_schema(QString pyFile) :pyFile(std::move(pyFile)) { }
bool operator()(EffectSchema const& schema) const
{
return schema.pyFile == pyFile;
}
};
// deleteEffect helper
struct find_effect : std::unary_function<EffectDefinition, bool>
{
QString effectName;
find_effect(QString effectName) :effectName(std::move(effectName)) { }
bool operator()(EffectDefinition const& effectDefinition) const
{
return effectDefinition.name == effectName;
}
};
EffectFileHandler* EffectFileHandler::efhInstance;
EffectFileHandler::EffectFileHandler(const QString& rootPath, const QJsonDocument& effectConfig, QObject* parent)
@ -61,7 +39,9 @@ QString EffectFileHandler::deleteEffect(const QString& effectName)
{
QString resultMsg;
std::list<EffectDefinition> effectsDefinition = getEffects();
std::list<EffectDefinition>::iterator it = std::find_if(effectsDefinition.begin(), effectsDefinition.end(), find_effect(effectName));
std::list<EffectDefinition>::iterator it = std::find_if(effectsDefinition.begin(), effectsDefinition.end(),
[&effectName](const EffectDefinition& effectDefinition) {return effectDefinition.name == effectName; }
);
if (it != effectsDefinition.end())
{
@ -117,7 +97,9 @@ QString EffectFileHandler::saveEffect(const QJsonObject& message)
QString scriptName = message["script"].toString();
std::list<EffectSchema> effectsSchemas = getEffectSchemas();
std::list<EffectSchema>::iterator it = std::find_if(effectsSchemas.begin(), effectsSchemas.end(), find_schema(scriptName));
std::list<EffectSchema>::iterator it = std::find_if(effectsSchemas.begin(), effectsSchemas.end(),
[&scriptName](const EffectSchema& schema) {return schema.pyFile == scriptName; }
);
if (it != effectsSchemas.end())
{
@ -132,17 +114,20 @@ QString EffectFileHandler::saveEffect(const QJsonObject& message)
if (!effectArray.empty())
{
if (message["name"].toString().trimmed().isEmpty() || message["name"].toString().trimmed().startsWith(":"))
QString effectName = message["name"].toString();
if (effectName.trimmed().isEmpty() || effectName.trimmed().startsWith(":"))
{
return "Can't save new effect. Effect name is empty or begins with a dot.";
}
effectJson["name"] = message["name"].toString();
effectJson["name"] = effectName;
effectJson["script"] = message["script"].toString();
effectJson["args"] = message["args"].toObject();
std::list<EffectDefinition> availableEffects = getEffects();
std::list<EffectDefinition>::iterator iter = std::find_if(availableEffects.begin(), availableEffects.end(), find_effect(message["name"].toString()));
std::list<EffectDefinition>::iterator iter = std::find_if(availableEffects.begin(), availableEffects.end(),
[&effectName](const EffectDefinition& effectDefinition) {return effectDefinition.name == effectName; }
);
QFileInfo newFileName;
if (iter != availableEffects.end())
@ -150,12 +135,12 @@ QString EffectFileHandler::saveEffect(const QJsonObject& message)
newFileName.setFile(iter->file);
if (newFileName.absoluteFilePath().startsWith(':'))
{
return "The effect name '" + message["name"].toString() + "' is assigned to an internal effect. Please rename your effect.";
return "The effect name '" + effectName + "' is assigned to an internal effect. Please rename your effect.";
}
}
else
{
QString f = effectArray[0].toString().replace("$ROOT", _rootPath) + '/' + message["name"].toString().replace(QString(" "), QString("")) + QString(".json");
QString f = effectArray[0].toString().replace("$ROOT", _rootPath) + '/' + effectName.replace(QString(" "), QString("")) + QString(".json");
newFileName.setFile(f);
}

View File

@ -36,6 +36,6 @@ add_library(flatbufserver
target_link_libraries(flatbufserver
hyperion-utils
flatbuffers
Qt5::Network
Qt5::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Core
)

View File

@ -236,7 +236,7 @@ QJsonObject AmlogicGrabber::discover(const QJsonObject& params)
QSize screenSize = _fbGrabber.getScreenSize();
if ( !screenSize.isEmpty() )
{
int fbIdx = _fbGrabber.getPath().rightRef(1).toInt();
int fbIdx = _fbGrabber.getPath().right(1).toInt();
DebugIf(verbose, _log, "FB device [%s] found with resolution: %dx%d", QSTRING_CSTR(_fbGrabber.getPath()), screenSize.width(), screenSize.height());
QJsonArray fps = { 1, 5, 10, 15, 20, 25, 30};

View File

@ -6,7 +6,7 @@
// Constants
namespace {
const bool verbose = true;
const bool verbose = false;
} //End of constants
DirectXGrabber::DirectXGrabber(int display, int cropLeft, int cropRight, int cropTop, int cropBottom)

View File

@ -208,7 +208,7 @@ QJsonObject FramebufferFrameGrabber::discover(const QJsonObject& params)
QFileInfoList::const_iterator deviceFileIterator;
for (deviceFileIterator = deviceFiles.constBegin(); deviceFileIterator != deviceFiles.constEnd(); ++deviceFileIterator)
{
fbIdx = (*deviceFileIterator).fileName().rightRef(1).toInt();
fbIdx = (*deviceFileIterator).fileName().right(1).toInt();
QString device = (*deviceFileIterator).absoluteFilePath();
DebugIf(verbose, _log, "FB device [%s] found", QSTRING_CSTR(device));

View File

@ -2,9 +2,6 @@
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/qt)
find_package(Qt5Widgets REQUIRED)
include_directories( ${X11_INCLUDES} )
FILE ( GLOB QT_GRAB_SOURCES "${CURRENT_HEADER_DIR}/Qt*.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.cpp" )
@ -12,5 +9,5 @@ add_library(qt-grabber ${QT_GRAB_SOURCES} )
target_link_libraries(qt-grabber
hyperion
Qt5::Widgets
${QT_LIBRARIES}
)

View File

@ -5,7 +5,6 @@
#include <QPixmap>
#include <QWindow>
#include <QGuiApplication>
#include <QWidget>
#include <QScreen>
#include <QJsonObject>
#include <QJsonArray>

View File

@ -172,7 +172,6 @@ bool MFGrabber::init()
}
}
return _initialized;
}
@ -194,6 +193,7 @@ HRESULT MFGrabber::init_device(QString deviceName, DeviceProperties props)
IMFAttributes* deviceAttributes = nullptr, *sourceReaderAttributes = nullptr;
IMFMediaType* type = nullptr;
HRESULT hr = S_OK;
IAMVideoProcAmp* pProcAmp = nullptr;
Debug(_log, "Init %s, %d x %d @ %d fps (%s)", QSTRING_CSTR(deviceName), props.width, props.height, props.fps, QSTRING_CSTR(pixelFormatToString(pixelformat)));
DebugIf (verbose, _log, "Symbolic link: %s", QSTRING_CSTR(props.symlink));
@ -233,7 +233,6 @@ HRESULT MFGrabber::init_device(QString deviceName, DeviceProperties props)
else
Debug(_log, "Device opened");
IAMVideoProcAmp *pProcAmp = nullptr;
if (SUCCEEDED(device->QueryInterface(IID_PPV_ARGS(&pProcAmp))))
{
for (auto control : _deviceControls[deviceName])
@ -402,7 +401,7 @@ void MFGrabber::enumVideoCaptureDevices()
if (SUCCEEDED(devices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &symlink, &length)))
{
QList<DeviceProperties> devicePropertyList;
QString dev = QString::fromUtf16((const ushort*)name);
QString dev = QString::fromUtf16((const char16_t*)name);
IMFMediaSource *pSource = nullptr;
if (SUCCEEDED(devices[i]->ActivateObject(IID_PPV_ARGS(&pSource))))
@ -429,7 +428,7 @@ void MFGrabber::enumVideoCaptureDevices()
if (pixelformat != PixelFormat::NO_CHANGE)
{
DeviceProperties properties;
properties.symlink = QString::fromUtf16((const ushort*)symlink);
properties.symlink = QString::fromUtf16((const char16_t*)symlink);
properties.width = width;
properties.height = height;
properties.fps = numerator / denominator;
@ -462,7 +461,7 @@ void MFGrabber::enumVideoCaptureDevices()
control.minValue = minVal;
control.maxValue = maxVal;
control.step = stepVal;
control.default = defaultVal;
control.def = defaultVal;
long currentVal;
if (SUCCEEDED(videoProcAmp->Get(it.key(), &currentVal, &flag)))
@ -515,9 +514,11 @@ void MFGrabber::start_capturing()
{
HRESULT hr = _sourceReader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, NULL, NULL);
if (!SUCCEEDED(hr))
{
Error(_log, "ReadSample (%i)", hr);
}
}
}
void MFGrabber::process_image(const void *frameImageBuffer, int size)
{
@ -784,7 +785,7 @@ QJsonArray MFGrabber::discover(const QJsonObject& params)
property["step"] = control.step;
property["current"] = control.currentValue;
controls[control.property] = property;
controls_default[control.property] = control.default;
controls_default[control.property] = control.def;
}
device["properties"] = controls;

View File

@ -124,12 +124,15 @@ public:
// Variables declaration
IMFMediaBuffer* buffer = nullptr;
BYTE* data = nullptr;
DWORD maxLength = 0, currentLength = 0;
if (FAILED(hrStatus))
{
_hrStatus = hrStatus;
_com_error error(_hrStatus);
Error(_grabber->_log, "%s", error.ErrorMessage());
Error(_grabber->_log, "0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -145,18 +148,15 @@ public:
_hrStatus = pSample->ConvertToContiguousBuffer(&buffer);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Buffer conversion failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Buffer conversion failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
BYTE* data = nullptr;
DWORD maxLength = 0, currentLength = 0;
_hrStatus = buffer->Lock(&data, &maxLength, &currentLength);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Access to the buffer memory failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Access to the buffer memory failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -165,8 +165,7 @@ public:
_hrStatus = buffer->Unlock();
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Unlocking the buffer memory failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Unlocking the buffer memory failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
}
done:
@ -183,7 +182,7 @@ public:
return _hrStatus;
}
HRESULT SourceReaderCB::InitializeVideoEncoder(IMFMediaType* type, PixelFormat format)
HRESULT InitializeVideoEncoder(IMFMediaType* type, PixelFormat format)
{
_pixelformat = format;
if (format == PixelFormat::MJPEG || format == PixelFormat::BGR24 || format == PixelFormat::NO_CHANGE)
@ -198,8 +197,7 @@ public:
_hrStatus = CoCreateInstance(CLSID_CColorConvertDMO, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&_transform);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Creation of the Color Converter failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Creation of the Color Converter failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -207,8 +205,7 @@ public:
_hrStatus = _transform->SetInputType(0, type, 0);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Setting the input media type failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Setting the input media type failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -216,8 +213,7 @@ public:
_hrStatus = MFCreateMediaType(&output);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Creating a new media type failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Creating a new media type failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -225,8 +221,7 @@ public:
_hrStatus = type->CopyAllItems(output);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Copying of all attributes from input to output media type failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Copying of all attributes from input to output media type failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -253,8 +248,7 @@ public:
_hrStatus = _transform->SetOutputType(0, output, 0);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Setting the output media type failed => %s", error.ErrorMessage());
Error(_grabber->_log, "Setting the output media type failed => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -262,8 +256,7 @@ public:
_hrStatus = _transform->GetInputStatus(0, &mftStatus);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Failed to query the input stream for more data => %s", error.ErrorMessage());
Error(_grabber->_log, "Failed to query the input stream for more data => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -283,7 +276,7 @@ public:
return _hrStatus;
}
BOOL SourceReaderCB::isBusy()
BOOL isBusy()
{
EnterCriticalSection(&_critsec);
BOOL result = _isBusy;
@ -310,18 +303,18 @@ private:
DeleteCriticalSection(&_critsec);
}
IMFSample* SourceReaderCB::TransformSample(IMFTransform* transform, IMFSample* in_sample)
IMFSample* TransformSample(IMFTransform* transform, IMFSample* in_sample)
{
IMFSample* result = nullptr;
IMFMediaBuffer* out_buffer = nullptr;
MFT_OUTPUT_DATA_BUFFER outputDataBuffer = { 0 };
DWORD status = 0;
// Process the input sample
_hrStatus = transform->ProcessInput(0, in_sample, 0);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Failed to process the input sample => %s", error.ErrorMessage());
Error(_grabber->_log, "Failed to process the input sample => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -330,8 +323,7 @@ private:
_hrStatus = transform->GetOutputStreamInfo(0, &streamInfo);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Failed to retrieve buffer requirement for output current => %s", error.ErrorMessage());
Error(_grabber->_log, "Failed to retrieve buffer requirement for output current => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -339,8 +331,7 @@ private:
_hrStatus = MFCreateMemoryBuffer(streamInfo.cbSize, &out_buffer);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Failed to create an output media buffer => %s", error.ErrorMessage());
Error(_grabber->_log, "Failed to create an output media buffer => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -348,8 +339,7 @@ private:
_hrStatus = MFCreateSample(&result);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Failed to create an empty media sample => %s", error.ErrorMessage());
Error(_grabber->_log, "Failed to create an empty media sampl => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -357,8 +347,7 @@ private:
_hrStatus = result->AddBuffer(out_buffer);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Failed to add the output media buffer to the media sample => %s", error.ErrorMessage());
Error(_grabber->_log, "Failed to add the output media buffer to the media sample => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
goto done;
}
@ -369,14 +358,11 @@ private:
outputDataBuffer.pEvents = nullptr;
outputDataBuffer.pSample = result;
DWORD status = 0;
// Generate the output sample
_hrStatus = transform->ProcessOutput(0, 1, &outputDataBuffer, &status);
if (FAILED(_hrStatus))
{
_com_error error(_hrStatus);
Error(_grabber->_log, "Failed to generate the output sample => %s", error.ErrorMessage());
Error(_grabber->_log, "Failed to generate the output sample => 0x%08x: %s", _hrStatus, std::system_category().message(_hrStatus).c_str());
}
else
{

View File

@ -4,7 +4,6 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/x11)
# Find X11
find_package(X11 REQUIRED)
find_package(Qt5Widgets REQUIRED)
include_directories( ${X11_INCLUDES} )
@ -21,5 +20,5 @@ target_link_libraries(x11-grabber
${X11_LIBRARIES}
${X11_Xrandr_LIB}
${X11_Xrender_LIB}
Qt5::Widgets
${QT_LIBRARIES}
)

View File

@ -378,7 +378,11 @@ void X11Grabber::setCropping(int cropLeft, int cropRight, int cropTop, int cropB
}
}
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool X11Grabber::nativeEventFilter(const QByteArray & eventType, void * message, qintptr * /*result*/)
#else
bool X11Grabber::nativeEventFilter(const QByteArray & eventType, void * message, long int * /*result*/)
#endif
{
if (!_XRandRAvailable || eventType != "xcb_generic_event_t") {
return false;

View File

@ -3,11 +3,6 @@ SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/xcb)
find_package(XCB COMPONENTS SHM IMAGE RENDER RANDR REQUIRED)
find_package(Qt5Widgets REQUIRED)
if (NOT APPLE)
find_package(Qt5X11Extras REQUIRED)
endif()
include_directories(${XCB_INCLUDE_DIRS})
@ -17,11 +12,12 @@ add_library(xcb-grabber ${XCB_SOURCES})
target_link_libraries(xcb-grabber
hyperion
Qt5::X11Extras
Qt5::Widgets
${XCB_LIBRARIES}
${QT_LIBRARIES}
)
if (NOT APPLE)
target_link_libraries(xcb-grabber Qt5::X11Extras)
target_link_libraries(
xcb-grabber
)
endif()

View File

@ -8,10 +8,6 @@
#include <QCoreApplication>
#ifndef __APPLE__
#include <QX11Info>
#endif
#include <memory>
// Constants
@ -454,7 +450,11 @@ void XcbGrabber::setCropping(int cropLeft, int cropRight, int cropTop, int cropB
updateScreenDimensions(true);
}
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool XcbGrabber::nativeEventFilter(const QByteArray & eventType, void * message, qintptr * /*result*/)
#else
bool XcbGrabber::nativeEventFilter(const QByteArray & eventType, void * message, long int * /*result*/)
#endif
{
if (!_XcbRandRAvailable || eventType != "xcb_generic_event_t" || _XcbRandREventBase == -1)
return false;
@ -477,7 +477,7 @@ xcb_render_pictformat_t XcbGrabber::findFormatForVisual(xcb_visualid_t visual) c
#ifdef __APPLE__
int screen = 0;
#else
int screen = QX11Info::appScreen();
int screen = _screen_num;
#endif
xcb_render_pictscreen_iterator_t sit =
xcb_render_query_pict_formats_screens_iterator(formats.get());

View File

@ -10,6 +10,6 @@ add_library(jsonserver ${JsonServer_SOURCES} )
target_link_libraries(jsonserver
hyperion-api
hyperion
Qt5::Network
Qt5::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Gui
)

View File

@ -3,7 +3,7 @@
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/leddevice)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/leddevice)
find_package(Qt5 COMPONENTS Network SerialPort REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network SerialPort REQUIRED)
include_directories(
dev_hid
@ -85,8 +85,8 @@ target_link_libraries(leddevice
hyperion
hyperion-utils
${CMAKE_THREAD_LIBS_INIT}
Qt5::Network
Qt5::SerialPort
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::SerialPort
ssdp
)

View File

@ -16,7 +16,12 @@
#include <QDir>
LedDeviceRegistry LedDeviceWrapper::_ledDeviceMap {};
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
QRecursiveMutex LedDeviceWrapper::_ledDeviceMapLock;
#else
QMutex LedDeviceWrapper::_ledDeviceMapLock{ QMutex::Recursive };
#endif
LedDeviceWrapper::LedDeviceWrapper(Hyperion* hyperion)
: QObject(hyperion)

View File

@ -325,8 +325,7 @@ QJsonObject LedDeviceAtmoOrb::discover(const QJsonObject& params)
close();
}
QMap<int, QHostAddress>::iterator i;
for (i = _services.begin(); i != _services.end(); ++i)
for (auto i = _services.begin(); i != _services.end(); ++i)
{
QJsonObject obj;

View File

@ -600,8 +600,7 @@ QJsonArray LedDeviceCololight::discover()
}
QJsonArray deviceList;
QMap<QString, QMap <QString, QString>>::iterator i;
for (i = _services.begin(); i != _services.end(); ++i)
for (auto i = _services.begin(); i != _services.end(); ++i)
{
QJsonObject obj;

View File

@ -250,12 +250,12 @@ bool LedDeviceNanoleaf::initLedsConfiguration()
QJsonObject jsonLayout = jsonPanelLayout[PANEL_LAYOUT].toObject();
int panelNum = jsonLayout[PANEL_NUM].toInt();
QJsonArray positionData = jsonLayout[PANEL_POSITIONDATA].toArray();
const QJsonArray positionData = jsonLayout[PANEL_POSITIONDATA].toArray();
std::map<int, std::map<int, int>> panelMap;
// Loop over all children.
foreach(const QJsonValue & value, positionData)
for(const QJsonValue & value : positionData)
{
QJsonObject panelObj = value.toObject();

View File

@ -1020,7 +1020,7 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
if ( deviceConfig[ CONFIG_COLOR_MODEL ].isString() )
{
_outputColorModel = deviceConfig[ CONFIG_COLOR_MODEL ].toString(QString(MODEL_RGB)).toInt();
_outputColorModel = deviceConfig[ CONFIG_COLOR_MODEL ].toString(QString(QChar(MODEL_RGB))).toInt();
}
else
{
@ -1029,7 +1029,7 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
if ( deviceConfig[ CONFIG_TRANS_EFFECT ].isString() )
{
_transitionEffect = static_cast<YeelightLight::API_EFFECT>( deviceConfig[ CONFIG_TRANS_EFFECT ].toString(QString(YeelightLight::API_EFFECT_SMOOTH)).toInt() );
_transitionEffect = static_cast<YeelightLight::API_EFFECT>( deviceConfig[ CONFIG_TRANS_EFFECT ].toString(QString(QChar(YeelightLight::API_EFFECT_SMOOTH))).toInt() );
}
else
{

View File

@ -252,7 +252,7 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const &reply)
default:
break;
}
errorReason = QString ("[%3 %4] - %5").arg(QString(httpStatusCode) , httpReason, advise);
errorReason = QString ("[%3 %4] - %5").arg(httpStatusCode).arg(httpReason, advise);
}
else {

View File

@ -286,7 +286,7 @@ QString ProviderRs232::discoverFirst()
// take first available USB serial port - currently no probing!
for (auto & port : QSerialPortInfo::availablePorts())
{
if (!port.isNull() && !port.isBusy())
if (!port.isNull())
{
Info(_log, "found serial device: %s", QSTRING_CSTR(port.portName()));
return port.portName();

View File

@ -33,12 +33,12 @@ target_link_libraries(protoclient
hyperion
hyperion-utils
protobuf
Qt5::Gui
Qt${QT_VERSION_MAJOR}::Gui
)
target_link_libraries(protoserver
hyperion
hyperion-utils
protoclient
Qt5::Gui
Qt${QT_VERSION_MAJOR}::Gui
)

View File

@ -9,6 +9,6 @@ add_library(ssdp
)
target_link_libraries(ssdp
Qt5::Network
Qt${QT_VERSION_MAJOR}::Network
webserver
)

View File

@ -300,7 +300,7 @@ QJsonArray SSDPDiscover::getServicesDiscoveredJson() const
{
QJsonArray result;
QMap<QString, SSDPService>::const_iterator i;
QMultiMap<QString, SSDPService>::const_iterator i;
for (i = _services.begin(); i != _services.end(); ++i)
{
//Debug(_log, "Device discovered at [%s]", QSTRING_CSTR( i.key() ));

View File

@ -7,7 +7,9 @@
#include <hyperion/AuthManager.h>
#include <QNetworkInterface>
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
#include <QNetworkConfigurationManager>
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
#include <QRandomGenerator>
@ -19,7 +21,9 @@ SSDPHandler::SSDPHandler(WebServer* webserver, quint16 flatBufPort, quint16 prot
: SSDPServer(parent)
, _webserver(webserver)
, _localAddress()
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
, _NCA(nullptr)
#endif
{
setFlatBufPort(flatBufPort);
setProtoBufPort(protoBufPort);
@ -46,13 +50,14 @@ void SSDPHandler::initServer()
// prep server
SSDPServer::initServer();
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
_NCA = new QNetworkConfigurationManager(this);
connect(_NCA, &QNetworkConfigurationManager::configurationChanged, this, &SSDPHandler::handleNetworkConfigurationChanged);
#endif
// listen for mSearchRequestes
connect(this, &SSDPServer::msearchRequestReceived, this, &SSDPHandler::handleMSearchRequest);
connect(_NCA, &QNetworkConfigurationManager::configurationChanged, this, &SSDPHandler::handleNetworkConfigurationChanged);
// get localAddress from interface
if(!getLocalAddress().isEmpty())
{
@ -138,6 +143,7 @@ void SSDPHandler::handleWebServerStateChange(bool newState)
}
}
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration &config)
{
// get localAddress from interface
@ -154,6 +160,7 @@ void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration
sendAnnounceList(true);
}
}
#endif
QString SSDPHandler::getLocalAddress() const
{

View File

@ -28,7 +28,7 @@ add_library(hyperion-utils
target_link_libraries(hyperion-utils
hyperion
python
Qt5::Core
Qt5::Gui
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
)

View File

@ -10,7 +10,11 @@ inline uint8_t clamp(int x)
void ColorSys::rgb2hsl(uint8_t red, uint8_t green, uint8_t blue, uint16_t & hue, float & saturation, float & luminance)
{
QColor color(red,green,blue);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
float h, s, l;
#else
qreal h, s, l;
#endif
color.getHslF(&h,&s,&l);
hue = h;
saturation = s;

View File

@ -17,7 +17,12 @@
#include <QThreadStorage>
#include <time.h>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
QRecursiveMutex Logger::MapLock;
#else
QMutex Logger::MapLock{ QMutex::Recursive };
#endif
QMap<QString,Logger*> Logger::LoggerMap { };
QAtomicInteger<int> Logger::GLOBAL_MIN_LOG_LEVEL { static_cast<int>(Logger::UNSET)};
@ -39,24 +44,25 @@ QThreadStorage<Logger::T_LOG_MESSAGE> RepeatMessage;
QString getApplicationName()
{
#ifdef __GLIBC__
const char* _appname_char = program_invocation_short_name;
#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
return QString(_appname_char).toLower();
//#ifdef __GLIBC__
// const char* _appname_char = program_invocation_short_name;
//#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
// return QString(_appname_char).toLower();
//
return "";
}
} // namespace

View File

@ -7,7 +7,10 @@
#include <utils/jsonschema/QJsonSchemaChecker.h>
#include <utils/jsonschema/QJsonUtils.h>
QJsonSchemaChecker::QJsonSchemaChecker()
QJsonSchemaChecker::QJsonSchemaChecker() :
_ignoreRequired(false),
_error(false),
_schemaError(false)
{
// empty
}
@ -26,6 +29,16 @@ bool QJsonSchemaChecker::setSchema(const QJsonObject & schema)
return true;
}
void QJsonSchemaChecker::setMessage(const QString& message)
{
_messages.append(_currentPath.join("") + ": " + message);
}
QStringList QJsonSchemaChecker::getMessages() const
{
return _messages;
}
QPair<bool, bool> QJsonSchemaChecker::validate(const QJsonObject& value, bool ignoreRequired)
{
// initialize state
@ -73,7 +86,7 @@ void QJsonSchemaChecker::validate(const QJsonValue & value, const QJsonObject &s
QJsonObject::const_iterator defaultValue = schema.find("default");
if (attribute == "type")
checkType(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkType(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "properties")
{
if (value.isObject())
@ -117,13 +130,13 @@ void QJsonSchemaChecker::validate(const QJsonValue & value, const QJsonObject &s
}
}
else if (attribute == "minimum")
checkMinimum(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkMinimum(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "maximum")
checkMaximum(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkMaximum(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "minLength")
checkMinLength(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkMinLength(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "maxLength")
checkMaxLength(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkMaxLength(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "items")
{
if (value.isArray())
@ -136,13 +149,13 @@ void QJsonSchemaChecker::validate(const QJsonValue & value, const QJsonObject &s
}
}
else if (attribute == "minItems")
checkMinItems(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkMinItems(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "maxItems")
checkMaxItems(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkMaxItems(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "uniqueItems")
checkUniqueItems(value, attributeValue);
else if (attribute == "enum")
checkEnum(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue::Null));
checkEnum(value, attributeValue, (defaultValue != schema.end() ? *defaultValue : QJsonValue(QJsonValue::Null)));
else if (attribute == "required")
; // nothing to do. value is present so always oke
else if (attribute == "id")
@ -161,16 +174,6 @@ void QJsonSchemaChecker::validate(const QJsonValue & value, const QJsonObject &s
}
}
void QJsonSchemaChecker::setMessage(const QString & message)
{
_messages.append(_currentPath.join("") +": "+message);
}
QStringList QJsonSchemaChecker::getMessages() const
{
return _messages;
}
void QJsonSchemaChecker::checkType(const QJsonValue& value, const QJsonValue& schema, const QJsonValue& defaultValue)
{
QString type = schema.toString();
@ -230,6 +233,9 @@ void QJsonSchemaChecker::checkProperties(const QJsonObject & value, const QJsonO
{
validate(value[property], propertyValue.toObject());
}
else if (verifyDeps(property, value, schema))
{
}
else if (required != propertyValue.toObject().end() && propertyValue.toObject().find("required").value().toBool() && !_ignoreRequired)
{
_error = true;
@ -250,6 +256,25 @@ void QJsonSchemaChecker::checkProperties(const QJsonObject & value, const QJsonO
}
}
bool QJsonSchemaChecker::verifyDeps(const QString& property, const QJsonObject& value, const QJsonObject& schema)
{
if (schema[property].toObject().contains("options") && (schema[property].toObject())["options"].toObject().contains("dependencies"))
{
const QJsonObject& depends = ((schema[property].toObject())["options"].toObject())["dependencies"].toObject();
if (depends.keys().size() > 0)
{
QString firstName = depends.keys().first();
if (value.contains(firstName))
{
if (value[firstName] != depends[firstName])
return true;
}
}
}
return false;
}
void QJsonSchemaChecker::checkDependencies(const QJsonObject& value, const QJsonObject& schema)
{
for (QJsonObject::const_iterator i = schema.begin(); i != schema.end(); ++i)

View File

@ -23,5 +23,5 @@ target_link_libraries(webserver
hyperion
hyperion-utils
hyperion-api
Qt5::Network
Qt${QT_VERSION_MAJOR}::Network
)

View File

@ -36,7 +36,7 @@ void QtHttpServerWrapper::incomingConnection (qintptr handle)
QtHttpServer::QtHttpServer (QObject * parent)
: QObject (parent)
, m_useSsl (false)
, m_serverName (QStringLiteral ("The Qt5 HTTP Server"))
, m_serverName (QStringLiteral ("The Qt6 HTTP Server"))
, m_netOrigin (NetOrigin::getInstance())
{
m_sockServer = new QtHttpServerWrapper (this);

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-aml)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver
@ -30,9 +30,9 @@ target_link_libraries(${PROJECT_NAME}
amlogic-grabber
framebuffer-grabber
ssdp
Qt5::Core
Qt5::Gui
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
if (ENABLE_AMLOGIC)

View File

@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-dispmanx)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
IF ( "${PLATFORM}" MATCHES rpi)
find_package(BCM REQUIRED)
ELSE()
@ -37,9 +38,9 @@ target_link_libraries( ${PROJECT_NAME}
dispmanx-grabber
${Dispmanx_LIBRARIES}
ssdp
Qt5::Core
Qt5::Gui
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_dispmanx" )

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-framebuffer)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver
@ -29,9 +29,10 @@ target_link_libraries( ${PROJECT_NAME}
flatbuffers
framebuffer-grabber
ssdp
Qt5::Core
Qt5::Gui
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
if (ENABLE_AMLOGIC)

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-osx)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver
@ -29,9 +29,10 @@ target_link_libraries( ${PROJECT_NAME}
flatbuffers
osx-grabber
ssdp
Qt5::Core
Qt5::Gui
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
install ( TARGETS ${PROJECT_NAME} DESTINATION "." COMPONENT "hyperion_osx" )

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-qt)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver
@ -35,9 +35,10 @@ target_link_libraries(${PROJECT_NAME}
flatbufserver
flatbuffers
ssdp
Qt5::Core
Qt5::Widgets
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
if(APPLE)

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-remote)
find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
# 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
@ -34,9 +34,10 @@ target_link_libraries(${PROJECT_NAME}
commandline
hyperion-utils
ssdp
Qt5::Gui
Qt5::Core
Qt5::Network)
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
if (ENABLE_AMLOGIC)
target_link_libraries(${PROJECT_NAME}

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-v4l2)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver
@ -29,9 +29,9 @@ target_link_libraries(${PROJECT_NAME}
flatbufserver
flatbuffers
ssdp
Qt5::Core
Qt5::Gui
Qt5::Network
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
if (ENABLE_AMLOGIC)

View File

@ -1,8 +1,9 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-x11)
find_package(Qt5Widgets REQUIRED)
find_package(X11 REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver
@ -38,10 +39,10 @@ target_link_libraries(${PROJECT_NAME}
${X11_LIBRARIES}
${X11_Xrandr_LIB}
${X11_Xrender_LIB}
Qt5::Core
Qt5::Gui
Qt5::Network
Qt5::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_x11" )

View File

@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.0.0)
project(hyperion-xcb)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver
${FLATBUFFERS_INCLUDE_DIRS}
@ -27,6 +29,9 @@ target_link_libraries(${PROJECT_NAME}
flatbuffers
xcb-grabber
ssdp
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
install (TARGETS ${PROJECT_NAME} DESTINATION "share/hyperion/bin" COMPONENT "hyperion_xcb")

View File

@ -12,7 +12,7 @@ else()
include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..)
endif()
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Gui Widgets REQUIRED)
# generate windows .rc file for this binary
if (WIN32)
@ -56,7 +56,10 @@ target_link_libraries(${PROJECT_NAME}
database
python
resources
Qt5::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets
)
if (NOT CMAKE_VERSION VERSION_LESS "3.12")
@ -71,7 +74,7 @@ endif (ENABLE_AVAHI)
if (ENABLE_AMLOGIC)
target_link_libraries(${PROJECT_NAME}
Qt5::Core
#Qt${QT_VERSION_MAJOR}::Core
pcre16 dl z
)
endif(ENABLE_AMLOGIC)
@ -172,12 +175,20 @@ endif()
# Deploy Qt DLLs into the binary folder.
# This is necessary for starting the application from within the IDE
if (WIN32)
get_target_property(QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXECUTABLE}" DIRECTORY)
find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_BIN_DIR}")
set(WINDEPLOYQT_PARAMS --verbose 0 --no-compiler-runtime --no-opengl-sw --no-system-d3d-compiler)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${WINDEPLOYQT_EXECUTABLE} ${WINDEPLOYQT_PARAMS} "$<TARGET_FILE:${PROJECT_NAME}>")
if (NOT WINDEPLOYQT_EXECUTABLE)
find_program(WINDEPLOYQT_EXECUTABLE windeployqt)
endif()
if (WINDEPLOYQT_EXECUTABLE AND NOT CMAKE_GITHUB_ACTION)
set(WINDEPLOYQT_PARAMS_RUNTIME --verbose 0 --no-compiler-runtime --no-opengl-sw --no-system-d3d-compiler)
message(STATUS "Found windeployqt: ${WINDEPLOYQT_EXECUTABLE} PATH_HINT:${QT_BIN_DIR}")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${WINDEPLOYQT_EXECUTABLE} ${WINDEPLOYQT_PARAMS_RUNTIME} "$<TARGET_FILE:${PROJECT_NAME}>")
endif()
endif(WIN32)
if(ENABLE_DEPLOY_DEPENDENCIES)

View File

@ -3,7 +3,7 @@
#include <QByteArray>
#include <QDir>
#include <QFile>
#include <QRegExp>
#include <QRegularExpression>
#include <QString>
#include <QTextStream>
@ -40,7 +40,7 @@ QStringList getProcessIdsByProcessName(const char *processName)
/* Walk through the snapshot of processes */
do
{
if (strcmp(processName, pe32.szExeFile) == 0)
if (QString::compare(processName, QString::fromUtf16(reinterpret_cast<char16_t*>(pe32.szExeFile)), Qt::CaseInsensitive) == 0)
listOfPids.append(QString::number(pe32.th32ProcessID));
} while(Process32Next(hProcessSnap, &pe32));
@ -54,8 +54,8 @@ QStringList getProcessIdsByProcessName(const char *processName)
dir.setSorting(QDir::Name | QDir::Reversed);
for (const QString & pid : dir.entryList()) {
QRegExp regexp("\\d*");
if (!regexp.exactMatch(pid))
QRegularExpression regexp("^\\d*$");
if (!regexp.match(pid).hasMatch())
{
/* Not a number, can not be PID */
continue;

View File

@ -66,7 +66,9 @@ void SysTray::iconActivated(QSystemTrayIcon::ActivationReason reason)
void SysTray::createTrayIcon()
{
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
quitAction = new QAction(tr("&Quit"), this);
quitAction->setIcon(QPixmap(":/quit.svg"));

View File

@ -1,7 +1,7 @@
# Needed for testing non-public components
include_directories(../libsrc)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)
MACRO (link_to_hyperion TARGET)
target_link_libraries( ${TARGET} blackborder leddevice jsonserver hyperion-utils hyperion effectengine )
@ -25,19 +25,19 @@ add_executable(test_blackborderdetector TestBlackBorderDetector.cpp)
link_to_hyperion(test_blackborderdetector)
add_executable(test_qregexp TestQRegExp.cpp)
target_link_libraries(test_qregexp Qt5::Widgets)
target_link_libraries(test_qregexp Qt${QT_VERSION_MAJOR}::Widgets)
add_executable(test_qtscreenshot TestQtScreenshot.cpp)
target_link_libraries(test_qtscreenshot Qt5::Widgets)
target_link_libraries(test_qtscreenshot Qt${QT_VERSION_MAJOR}::Widgets)
if(ENABLE_X11)
find_package(X11 REQUIRED)
add_executable(test_x11performance TestX11Performance.cpp)
target_link_libraries(test_x11performance ${X11_LIBRARIES} Qt5::Widgets)
target_link_libraries(test_x11performance ${X11_LIBRARIES} Qt${QT_VERSION_MAJOR}::Widgets)
endif(ENABLE_X11)
add_executable(test_versions TestVersions.cpp)
target_link_libraries(test_versions Qt5::Core)
target_link_libraries(test_versions Qt${QT_VERSION_MAJOR}::Core)
######### These tests are broken. May they fix someone ##########

View File

@ -102,7 +102,7 @@ int main(int argc, char** argv)
qDebug() << "PASSED";
return 0;
}
catch (std::runtime_error exception)
catch (std::runtime_error& exception)
{
qDebug() << "FAILED";
qDebug() << exception.what();

View File

@ -3,7 +3,7 @@
#include <iostream>
// QT includes
#include <QRegExp>
#include <QRegularExpression>
#include <QString>
#include <QStringList>
@ -11,21 +11,21 @@ int main()
{
QString testString = "1-9, 11, 12,13,16-17";
QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
QRegularExpression overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
{
std::cout << "[1] Match found: " << (overallExp.exactMatch("5")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("4-")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("-4")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("3-9")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("1-90")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("1-90,100")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("1-90, 100")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("1-90, 100-200")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.exactMatch("1-90, 100-200, 100")?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("5").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("4-").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("-4").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("3-9").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("1-90").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("1-90,100").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("1-90, 100").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("1-90, 100-200").hasMatch()?"true":"false") << std::endl;
std::cout << "[1] Match found: " << (overallExp.match("1-90, 100-200, 100").hasMatch()?"true":"false") << std::endl;
}
{
if (!overallExp.exactMatch(testString)) {
if (!overallExp.match(testString).hasMatch()) {
std::cout << "No correct match" << std::endl;
return -1;
}

View File

@ -4,7 +4,6 @@
// QT includes
#include <QApplication>
#include <QDesktopWidget>
#include <QPixmap>
#include <QFile>
#include <QRgb>
@ -23,7 +22,7 @@ void createScreenshot(const int cropHorizontal, const int cropVertical, const in
const QRect screenSize = screen->availableGeometry();
const int croppedWidth = screenSize.width() - 2*cropVertical;
const int croppedHeight = screenSize.height() - 2*cropHorizontal;
const QPixmap fullSizeScreenshot = screen->grabWindow(QApplication::desktop()->winId(), cropVertical, cropHorizontal, croppedWidth, croppedHeight);
const QPixmap fullSizeScreenshot = screen->grabWindow(0, cropVertical, cropHorizontal, croppedWidth, croppedHeight);
// Scale the screenshot to the required size
const int width = fullSizeScreenshot.width()/decimation;

View File

@ -1,8 +1,9 @@
# this is only available on real pi
IF ( "${PLATFORM}" MATCHES rpi)
# Find the BCM-package (VC control)
find_package(Qt5Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui REQUIRED)
# Find the BCM-package (VC control)
find_package(BCM REQUIRED)
include_directories(${BCM_INCLUDE_DIRS})
@ -14,5 +15,5 @@ IF ( "${PLATFORM}" MATCHES rpi)
target_link_libraries(dispmanx2png
dispmanx-grabber
Qt5::Gui)
Qt${QT_VERSION_MAJOR::Gui)
ENDIF()