├── .github └── workflows │ ├── alpine-arm64-qt-build.yml │ ├── clazy-report.yaml │ ├── create-release.yaml │ ├── linux-build-from-source.yml │ ├── linux-build.yaml │ ├── linux-flatpak-build.yaml │ ├── linux-portable-build.yaml │ ├── windows-build.yaml │ └── windows-portable-build.yaml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README-static-build.md ├── README.md ├── build-script ├── Dockerfile.raspbian ├── build-from-source-static.sh ├── build-from-source.sh ├── build-static-ffmpeg.sh ├── build-static-qt-dependency.sh ├── build-static-qt-for-arm64.sh ├── build-static-qt-from-source.bat ├── build-static-qt-from-source.sh ├── build-static-xcb-utils.sh ├── cmake_local_build.sh └── docker │ └── build-arm64-qt.sh ├── com.openterface.openterfaceQT.desktop ├── com.openterface.openterfaceQT.metainfo.xml ├── com.openterface.openterfaceQT.yaml ├── config ├── keyboards │ ├── azerty_fr.json │ ├── japanese.json │ ├── keyboard_layouts.qrc │ ├── qwerty_dk.json │ ├── qwerty_se.json │ ├── qwerty_uk.json │ ├── qwerty_us.json │ └── qwertz_de.json └── languages │ ├── language.qrc │ ├── openterface_da.qm │ ├── openterface_da.ts │ ├── openterface_de.qm │ ├── openterface_de.ts │ ├── openterface_en.qm │ ├── openterface_en.ts │ ├── openterface_fr.qm │ ├── openterface_fr.ts │ ├── openterface_ja.qm │ ├── openterface_ja.ts │ ├── openterface_se.qm │ └── openterface_se.ts ├── doc ├── feature.md ├── flatpak_installation.md ├── keyboard_layout_adding.md ├── multi_language.md ├── resolutions.md ├── rpi_installation.md └── socket_example.ipynb ├── docker ├── Dockerfile.alpine ├── Dockerfile.raspbian ├── README.md ├── build-alpine.sh ├── build-and-push.sh ├── build-app-alpine.sh ├── build-arm64-qt-alpine.sh └── docker-compose.alpine.yml ├── driver ├── linux │ ├── Makefile │ ├── README.md │ ├── ch341.c │ ├── ch341.h │ └── drivers.qrc └── windows │ ├── CH341PORTSA64.DLL │ ├── CH341PT.DLL │ ├── CH341PTA64.DLL │ ├── CH341SER.CAT │ ├── CH341SER.INF │ ├── ch341ser.PNF │ └── drivers.qrc ├── global.h ├── host ├── HostManager.cpp ├── HostManager.h ├── audiomanager.cpp ├── audiomanager.h ├── audiothread.cpp ├── audiothread.h ├── cameramanager.cpp ├── cameramanager.h ├── usbcontrol.cpp └── usbcontrol.h ├── images ├── capture.svg ├── content_dark_eng.png ├── contrast.svg ├── full_screen.svg ├── fullscreen.svg ├── icon_128.ico ├── icon_128.png ├── icon_256.png ├── icon_256.svg ├── icon_32.ico ├── icon_32.png ├── icon_64.ico ├── icon_64.png ├── keyboard-down.svg ├── keyboard-pressed.svg ├── keyboard-up.svg ├── keyboard.svg ├── mouse-default.svg ├── mouse-left-button.svg ├── mouse-middle-button.svg ├── mouse-right-button.svg ├── paste.svg ├── screen_scale.svg ├── screensaver.svg ├── shutter.svg ├── zoom_fit.svg ├── zoom_in.svg └── zoom_out.svg ├── installer.iss ├── installer.nsi ├── lib ├── libusb-1.0.a ├── libusb-1.0.dll ├── libusb-1.0.lib └── libusb-1.0 │ └── libusb.h ├── main.cpp ├── openterfaceQT.pro ├── openterfaceQT.rc ├── packaging ├── appimage │ ├── openterfaceQT.appdata.xml │ └── openterfaceQT.desktop ├── debian │ └── control └── rpm │ └── spec ├── qt-installer-noninteractive.qs ├── regex ├── RegularExpression.cpp └── RegularExpression.h ├── resources └── version.h ├── scripts ├── AST.h ├── KeyboardMouse.cpp ├── KeyboardMouse.h ├── Lexer.cpp ├── Lexer.h ├── Parser.cpp ├── Parser.h ├── Token.h ├── scriptEditor.cpp ├── scriptEditor.h ├── semanticAnalyzer.cpp └── semanticAnalyzer.h ├── serial ├── SerialPortManager.cpp ├── SerialPortManager.h ├── TEST └── ch9329.h ├── server ├── tcpServer.cpp └── tcpServer.h ├── target ├── KeyboardLayouts.cpp ├── KeyboardLayouts.h ├── KeyboardManager.cpp ├── KeyboardManager.h ├── Keymapping.h ├── MouseManager.cpp ├── MouseManager.h ├── mouseeventdto.cpp └── mouseeventdto.h ├── ui ├── TaskManager.cpp ├── TaskManager.h ├── advance │ ├── envdialog.cpp │ ├── envdialog.h │ ├── envdialog.ui │ ├── firmwareupdatedialog.cpp │ ├── firmwareupdatedialog.h │ ├── scripttool.cpp │ ├── scripttool.h │ ├── serialportdebugdialog.cpp │ └── serialportdebugdialog.h ├── cameraadjust.cpp ├── cameraadjust.h ├── cornerwidget │ ├── cornerwidgetmanager.cpp │ └── cornerwidgetmanager.h ├── globalsetting.cpp ├── globalsetting.h ├── help │ ├── helppane.cpp │ ├── helppane.h │ ├── versioninfomanager.cpp │ └── versioninfomanager.h ├── inputhandler.cpp ├── inputhandler.h ├── languagemanager.cpp ├── languagemanager.h ├── loghandler.cpp ├── loghandler.h ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.qrc ├── mainwindow.ui ├── preferences │ ├── audiopage.cpp │ ├── audiopage.h │ ├── cameraadjust.cpp │ ├── cameraadjust.h │ ├── fontstyle.h │ ├── fpsspinbox.cpp │ ├── fpsspinbox.h │ ├── logpage.cpp │ ├── logpage.h │ ├── settingdialog.cpp │ ├── settingdialog.h │ ├── settingdialog.ui │ ├── targetcontrolpage.cpp │ ├── targetcontrolpage.h │ ├── videopage.cpp │ └── videopage.h ├── screensavermanager.cpp ├── screensavermanager.h ├── screenscale.cpp ├── screenscale.h ├── statusbar │ ├── statusbarmanager.cpp │ ├── statusbarmanager.h │ ├── statuswidget.cpp │ └── statuswidget.h ├── statusevents.h ├── toolbar │ ├── toggleswitch.cpp │ ├── toggleswitch.h │ ├── toolbarmanager.cpp │ └── toolbarmanager.h ├── videopane.cpp └── videopane.h ├── update_version.py ├── usb ├── usb_win.cpp └── usb_win.h ├── valgrind.supp └── video ├── firmwarewriter.cpp ├── firmwarewriter.h ├── ms2109.h ├── videohid.cpp └── videohid.h /.github/workflows/linux-build-from-source.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Linux build from Source 3 | 4 | on: 5 | workflow_dispatch: 6 | 7 | env: 8 | SOURCE_DIR: ${{ github.workspace }} 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-22.04 13 | 14 | steps: 15 | - name: Checkout code 16 | uses: actions/checkout@v2 17 | 18 | - name: Cache Dependencies 19 | id: cache-deps 20 | uses: actions/cache@v3 21 | with: 22 | path: ${{ env.SOURCE_DIR }}/qt-build/ 23 | key: dependencies-cache 24 | restore-keys: | 25 | dependencies-cache 26 | 27 | - name: Build Qt Dependencies 28 | if: steps.cache-deps.outputs.cache-hit != 'true' 29 | run: | 30 | bash ${{ env.SOURCE_DIR }}/build-script/build-static-qt-dependency.sh 31 | -------------------------------------------------------------------------------- /.github/workflows/linux-flatpak-build.yaml: -------------------------------------------------------------------------------- 1 | name: Linux flatpak build 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | tags: ["v*"] 7 | pull_request: 8 | branches: ["dev"] 9 | workflow_dispatch: 10 | 11 | env: 12 | ARTIFACT: openterfaceQT 13 | SOURCE_DIR: ${{ github.workspace }} 14 | FLATPAK_MANIFEST: "com.openterface.openterfaceQT.yaml" 15 | SOFTWERE_ID: "com.openterface.openterfaceQT" 16 | FLATPAK_BUILD_DIR: "build-dir" 17 | QT_VERSION: 6.4.2 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-22.04 22 | strategy: 23 | matrix: 24 | arch: [x86_64, aarch64] 25 | 26 | steps: 27 | 28 | 29 | - name: Checkout code 30 | uses: actions/checkout@v4 31 | with: 32 | submodules: recursive 33 | 34 | - name: Install dependencies for aarch64 35 | if: matrix.arch != 'x86_64' 36 | run: | 37 | sudo apt -y install docker 38 | 39 | - name: Set up QEMU for aarch64 40 | if: matrix.arch != 'x86_64' 41 | uses: docker/setup-qemu-action@v2 42 | with: 43 | platforms: arm64 44 | 45 | - name: Install flatpak 46 | run: | 47 | sudo apt update -y 48 | sudo apt install -y flatpak flatpak-builder qemu-user-static 49 | if [ "${{ matrix.arch }}" = "aarch64" ]; then 50 | sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu 51 | fi 52 | 53 | - name: Add flatpak shared-modules 54 | run: | 55 | git submodule add https://github.com/flathub/shared-modules.git 56 | 57 | - name: Read version from version.h 58 | id: read_version 59 | run: | 60 | VERSION=$(grep -oP '#define APP_VERSION "\K[^"]+' resources/version.h) 61 | echo "VERSION=$VERSION" >> $GITHUB_ENV 62 | 63 | - name: Add Flathub repository and install kde 64 | run: | 65 | flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo 66 | flatpak install --user --noninteractive flathub org.kde.Sdk/${{ matrix.arch }}/6.9 67 | flatpak install --user --noninteractive flathub org.kde.Platform/${{ matrix.arch }}/6.9 68 | 69 | - name: Initialize build directory 70 | run: | 71 | flatpak build-init ${{ env.FLATPAK_BUILD_DIR }} ${{ env.SOFTWERE_ID }} org.kde.Sdk//6.9 org.kde.Platform//6.9 ${{ matrix.arch }} 72 | 73 | - name: check configure script 74 | run: | 75 | ls -l .flatpak-builder/build/libusb-1 || true 76 | file .flatpak-builder/build/libusb-1/configure || true 77 | 78 | - name: Build Flatpak 79 | run: | 80 | flatpak-builder \ 81 | --user \ 82 | --install \ 83 | --force-clean \ 84 | --arch=${{ matrix.arch }} \ 85 | ${{ env.FLATPAK_BUILD_DIR }} \ 86 | ${{ env.FLATPAK_MANIFEST }} 87 | env: 88 | # Ensure cross-compilation for aarch64 89 | FLATPAK_ARCH: ${{ matrix.arch }} 90 | 91 | - name: Export Flatpak Bundle 92 | run: | 93 | mkdir -p repo-${{ matrix.arch }} 94 | flatpak build-export --arch=${{ matrix.arch }} repo-${{ matrix.arch }} ${{ env.FLATPAK_BUILD_DIR }} 95 | flatpak build-bundle --arch=${{ matrix.arch }} repo-${{ matrix.arch }} ${{ env.SOFTWERE_ID }}-${{ matrix.arch }}.flatpak ${{ env.SOFTWERE_ID }} 96 | env: 97 | FLATPAK_ARCH: ${{ matrix.arch }} 98 | 99 | - name: Upload flatpak artifact 100 | uses: actions/upload-artifact@v4 101 | with: 102 | name: openterfaceQT.${{ matrix.arch }}.flatpak 103 | path: ${{ env.SOFTWERE_ID }}-${{ matrix.arch }}.flatpak 104 | 105 | if-no-files-found: error -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pro.user.* 2 | build/* 3 | release/* 4 | aqtinstall.log 5 | debug/* 6 | .vscode 7 | openterfaceQT.pro.user* 8 | build-script/drivers/* 9 | build-script/ffmpeg-build/* 10 | build-script/temp/* 11 | .DS_Store 12 | .flatpak-builder/* 13 | .build-dir/* -------------------------------------------------------------------------------- /README-static-build.md: -------------------------------------------------------------------------------- 1 | # Static Build Notes for OpenTerface QT 2 | 3 | ## Static Plugin Imports 4 | 5 | When using static linking, dynamically loaded plugins are disabled. You need to import all required static plugins in your application code. Include the following code in your main.cpp file: 6 | 7 | ```cpp 8 | #include 9 | 10 | #if defined(QT_STATIC) 11 | // Platform plugin 12 | Q_IMPORT_PLUGIN(QXcbIntegrationPlugin) 13 | 14 | // Image formats 15 | Q_IMPORT_PLUGIN(QJpegPlugin) 16 | Q_IMPORT_PLUGIN(QGifPlugin) 17 | Q_IMPORT_PLUGIN(QPngPlugin) 18 | Q_IMPORT_PLUGIN(QSvgPlugin) 19 | 20 | // Media plugins if needed 21 | Q_IMPORT_PLUGIN(QFFmpegMediaPlugin) 22 | 23 | // Add any other required plugins 24 | #endif 25 | ``` 26 | 27 | Additionally, you'll need to add the corresponding plugin libraries to your CMake/qmake configuration: 28 | 29 | ```cmake 30 | # For CMake 31 | target_link_libraries(your_target PRIVATE 32 | Qt6::QXcbIntegrationPlugin 33 | Qt6::QJpegPlugin 34 | Qt6::QGifPlugin 35 | Qt6::QPngPlugin 36 | Qt6::QSvgPlugin 37 | # Add other required plugins 38 | ) 39 | ``` 40 | 41 | ## X11 Accessibility Bridge 42 | 43 | The X11 Accessibility Bridge is currently disabled in the static build because D-Bus or AT-SPI is missing. If accessibility features are required, add D-Bus support by: 44 | 45 | 1. Installing D-Bus development packages: 46 | ``` 47 | sudo apt-get install libdbus-1-dev libdbus-glib-1-dev 48 | ``` 49 | 50 | 2. Enable D-Bus in the Qt build: 51 | ``` 52 | -DFEATURE_dbus=ON 53 | ``` 54 | -------------------------------------------------------------------------------- /build-script/Dockerfile.raspbian: -------------------------------------------------------------------------------- 1 | FROM arm32v7/debian:bookworm 2 | 3 | ENV QT_VERSION=6.5.3 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | build-essential \ 7 | cmake \ 8 | git \ 9 | wget \ 10 | libfontconfig1-dev \ 11 | libfreetype6-dev \ 12 | libx11-dev \ 13 | libxext-dev \ 14 | libxfixes-dev \ 15 | libxi-dev \ 16 | libxrender-dev \ 17 | libxcb1-dev \ 18 | libx11-xcb-dev \ 19 | libxcb-glx0-dev \ 20 | libxkbcommon-dev \ 21 | libxkbcommon-x11-dev \ 22 | libglib2.0-dev \ 23 | libgl1-mesa-dev \ 24 | libglu1-mesa-dev \ 25 | freeglut3-dev \ 26 | libegl1-mesa-dev \ 27 | libdbus-1-dev \ 28 | libssl-dev \ 29 | libicu-dev \ 30 | && rm -rf /var/lib/apt/lists/* 31 | 32 | # Download and compile Qt 33 | RUN wget https://download.qt.io/official_releases/qt/6.5/${QT_VERSION}/single/qt-everywhere-src-${QT_VERSION}.tar.xz \ 34 | && tar xf qt-everywhere-src-${QT_VERSION}.tar.xz \ 35 | && cd qt-everywhere-src-${QT_VERSION} \ 36 | && ./configure -prefix /opt/Qt/${QT_VERSION} -opensource -confirm-license -release -nomake examples -nomake tests \ 37 | && make -j$(nproc) \ 38 | && make install \ 39 | && cd .. \ 40 | && rm -rf qt-everywhere-src-${QT_VERSION} qt-everywhere-src-${QT_VERSION}.tar.xz 41 | 42 | # Set Qt environment variables 43 | ENV PATH="/opt/Qt/${QT_VERSION}/bin:${PATH}" 44 | ENV QT_PLUGIN_PATH="/opt/Qt/${QT_VERSION}/plugins" 45 | ENV QML2_IMPORT_PATH="/opt/Qt/${QT_VERSION}/qml" 46 | ENV LD_LIBRARY_PATH="/opt/Qt/${QT_VERSION}/lib:${LD_LIBRARY_PATH}" 47 | 48 | WORKDIR /app 49 | 50 | COPY . . 51 | 52 | RUN cmake -B build -S . -DCMAKE_PREFIX_PATH="/opt/Qt/${QT_VERSION}" && \ 53 | cmake --build build -j$(nproc) 54 | 55 | CMD ["/app/build/openterfaceQT"] 56 | -------------------------------------------------------------------------------- /build-script/build-static-ffmpeg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Default behavior is to build and install 5 | BUILD_ENABLED=true 6 | INSTALL_ENABLED=true 7 | 8 | # Check for parameters 9 | for arg in "$@"; do 10 | case $arg in 11 | --no-build) 12 | BUILD_ENABLED=false 13 | shift 14 | ;; 15 | --no-install) 16 | INSTALL_ENABLED=false 17 | shift 18 | ;; 19 | *) 20 | echo "Usage: $0 [--no-build] [--no-install]" 21 | exit 1 22 | ;; 23 | esac 24 | done 25 | 26 | # Configuration 27 | BUILD_DIR="$(pwd)/ffmpeg-build" 28 | LIBUSB_VERSION=1.0.26 29 | NASM_VERSION="2.16.01" 30 | FFMPEG_VERSION=6.1.1 31 | 32 | mkdir -p "$BUILD_DIR" 33 | cd "$BUILD_DIR" 34 | 35 | # Build or Install libusb from source 36 | if $BUILD_ENABLED; then 37 | echo "Building libusb $LIBUSB_VERSION from source..." 38 | if [ ! -d "libusb" ]; then 39 | curl -L -o libusb.tar.bz2 "https://github.com/libusb/libusb/releases/download/v${LIBUSB_VERSION}/libusb-${LIBUSB_VERSION}.tar.bz2" 40 | tar xf libusb.tar.bz2 41 | mv "libusb-${LIBUSB_VERSION}" libusb 42 | rm libusb.tar.bz2 43 | fi 44 | 45 | cd libusb 46 | ./configure --prefix=/usr --enable-static --disable-shared --disable-udev 47 | make -j$(nproc) 48 | fi 49 | 50 | if $INSTALL_ENABLED; then 51 | echo "Installing libusb $LIBUSB_VERSION..." 52 | cd "$BUILD_DIR"/libusb 53 | sudo make install 54 | fi 55 | cd "$BUILD_DIR" 56 | 57 | # Install NASM 58 | if $BUILD_ENABLED; then 59 | echo "Installing NASM..." 60 | if [ ! -d "nasm-${NASM_VERSION}" ]; then 61 | curl -L -o nasm.tar.xz "https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}/nasm-${NASM_VERSION}.tar.xz" 62 | tar xf nasm.tar.xz 63 | rm nasm.tar.xz 64 | fi 65 | 66 | cd "nasm-${NASM_VERSION}" 67 | ./configure --prefix=/usr 68 | make -j$(nproc) 69 | fi 70 | 71 | if $INSTALL_ENABLED; then 72 | echo "Installing NASM..." 73 | cd "$BUILD_DIR"/nasm-${NASM_VERSION} 74 | sudo make install 75 | fi 76 | cd "$BUILD_DIR" 77 | 78 | # Build FFmpeg 79 | if $BUILD_ENABLED; then 80 | echo "Building FFmpeg $FFMPEG_VERSION from source..." 81 | if [ ! -d "FFmpeg-n${FFMPEG_VERSION}" ]; then 82 | curl -L -o ffmpeg.tar.gz "https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n${FFMPEG_VERSION}.tar.gz" 83 | tar -xzf ffmpeg.tar.gz 84 | rm ffmpeg.tar.gz 85 | fi 86 | 87 | cd "FFmpeg-n${FFMPEG_VERSION}" 88 | ./configure --prefix=/usr/local \ 89 | --disable-shared \ 90 | --enable-gpl \ 91 | --enable-version3 \ 92 | --disable-nonfree \ 93 | --disable-doc \ 94 | --disable-programs \ 95 | --enable-pic \ 96 | --enable-static 97 | make -j$(nproc) 98 | fi 99 | 100 | if $INSTALL_ENABLED; then 101 | echo "Installing FFmpeg $FFMPEG_VERSION..." 102 | cd "$BUILD_DIR"/FFmpeg-n${FFMPEG_VERSION} 103 | sudo make install 104 | sudo ldconfig 105 | fi 106 | cd "$BUILD_DIR" 107 | 108 | echo "FFMPEG have been processed successfully" -------------------------------------------------------------------------------- /build-script/build-static-qt-from-source.bat: -------------------------------------------------------------------------------- 1 | @echo on 2 | REM To install OpenTerface QT, you can run this script as an administrator. 3 | 4 | setlocal enabledelayedexpansion 5 | 6 | REM Configuration 7 | set QT_VERSION=6.5.3 8 | set QT_MAJOR_VERSION=6.5 9 | set INSTALL_PREFIX=C:\Qt6 10 | set BUILD_DIR=%cd%\qt-build 11 | set MODULES=qtbase qtshadertools qtmultimedia qtsvg qtserialport qttools 12 | set DOWNLOAD_BASE_URL=https://download.qt.io/archive/qt/%QT_MAJOR_VERSION%/%QT_VERSION%/submodules 13 | 14 | set PATH=C:\ProgramData\chocolatey\bin;C:\ProgramData\chocolatey\lib\ninja\tools;C:\ProgramData\chocolatey\lib\mingw\tools\mingw64\bin;%PATH% 15 | 16 | REM Check for Ninja 17 | where ninja >nul 2>nul 18 | if %errorlevel% neq 0 ( 19 | echo Ninja is not installed. Please install Ninja and ensure it is in your PATH. 20 | exit /b 1 21 | ) 22 | 23 | REM Create build directory 24 | mkdir "%BUILD_DIR%" 25 | cd "%BUILD_DIR%" 26 | 27 | REM Download and extract modules 28 | for %%m in (%MODULES%) do ( 29 | if not exist "%%m" ( 30 | curl -L -o "%%m.zip" "%DOWNLOAD_BASE_URL%/%%m-everywhere-src-%QT_VERSION%.zip" 31 | powershell -command "Expand-Archive -Path %%m.zip -DestinationPath ." 32 | move "%%m-everywhere-src-%QT_VERSION%" "%%m" 33 | del "%%m.zip" 34 | ) 35 | ) 36 | 37 | REM Build qtbase first 38 | cd "%BUILD_DIR%\qtbase" 39 | mkdir build 40 | cd build 41 | cmake -G "Ninja" ^ 42 | -DCMAKE_INSTALL_PREFIX="%INSTALL_PREFIX%" ^ 43 | -DBUILD_SHARED_LIBS=OFF ^ 44 | -DFEATURE_dbus=ON ^ 45 | -DFEATURE_sql=OFF ^ 46 | -DFEATURE_testlib=OFF ^ 47 | -DFEATURE_icu=OFF ^ 48 | -DFEATURE_opengl=ON ^ 49 | .. 50 | ninja 51 | ninja install 52 | 53 | REM Build other modules (including qttools) 54 | for %%m in (%MODULES%) do ( 55 | if /I not "%%m"=="qtbase" ( 56 | cd "%BUILD_DIR%\%%m" 57 | mkdir build 58 | cd build 59 | cmake -G "Ninja" ^ 60 | -DCMAKE_INSTALL_PREFIX="%INSTALL_PREFIX%" ^ 61 | -DCMAKE_PREFIX_PATH="%INSTALL_PREFIX%" ^ 62 | -DBUILD_SHARED_LIBS=OFF ^ 63 | .. 64 | ninja 65 | ninja install 66 | ) 67 | ) 68 | 69 | REM Quick fix: Add -loleaut32 to qnetworklistmanager.prl 70 | set PRL_FILE=%INSTALL_PREFIX%\plugins\networkinformation\qnetworklistmanager.prl 71 | if exist "%PRL_FILE%" ( 72 | echo Updating %PRL_FILE% to include -loleaut32... 73 | echo QMAKE_PRL_LIBS += -loleaut32 >> "%PRL_FILE%" 74 | ) else ( 75 | echo Warning: %PRL_FILE% not found. Please check the build process. 76 | ) 77 | 78 | REM Verify lupdate 79 | if exist "%INSTALL_PREFIX%\bin\lupdate.exe" ( 80 | echo lupdate.exe successfully built! 81 | ) else ( 82 | echo Error: lupdate.exe not found in %INSTALL_PREFIX%\bin 83 | exit /b 1 84 | ) -------------------------------------------------------------------------------- /com.openterface.openterfaceQT.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=openterfaceQT 4 | Exec=openterfaceQT 5 | Icon=com.openterface.openterfaceQT 6 | Comment=A software for control openterface-Mini-KVM. 7 | Categories=Utility; 8 | Terminal=false 9 | Keywords=openterface;open-source; -------------------------------------------------------------------------------- /com.openterface.openterfaceQT.yaml: -------------------------------------------------------------------------------- 1 | app-id: com.openterface.openterfaceQT 2 | runtime: org.kde.Platform 3 | runtime-version: "6.9" 4 | sdk: org.kde.Sdk 5 | command: openterfaceQT 6 | finish-args: 7 | - --share=ipc 8 | - --share=network 9 | - --socket=x11 10 | - --device=all 11 | - --filesystem=/run/udev:ro 12 | 13 | modules: 14 | - shared-modules/libusb/libusb.json 15 | 16 | - name: openterfaceQT 17 | buildsystem: qmake 18 | config-opts: 19 | - "LIBS+=-L/app/lib -lusb-1.0" 20 | - "INCLUDEPATH+=/app/include/libusb-1.0" 21 | sources: 22 | - type: git 23 | url: https://github.com/TechxArtisanStudio/Openterface_QT.git 24 | tag: 0.3.11 25 | commit: d7c0114524ebdd19512c5b3cb2398ad74f3aebf0 26 | 27 | build-options: 28 | env: 29 | QT_SELECT: qt6 30 | post-install: 31 | - install -Dm755 openterfaceQT /app/bin/openterfaceQT 32 | - install -Dm644 com.openterface.openterfaceQT.desktop /app/share/applications/com.openterface.openterfaceQT.desktop 33 | - install -Dm644 com.openterface.openterfaceQT.metainfo.xml /app/share/metainfo/com.openterface.openterfaceQT.metainfo.xml 34 | - install -Dm644 images/icon_128.png /app/share/icons/hicolor/128x128/apps/com.openterface.openterfaceQT.png 35 | -------------------------------------------------------------------------------- /config/keyboards/keyboard_layouts.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qwerty_us.json 5 | qwerty_uk.json 6 | azerty_fr.json 7 | qwertz_de.json 8 | qwerty_dk.json 9 | qwerty_se.json 10 | japanese.json 11 | 12 | -------------------------------------------------------------------------------- /config/languages/language.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | openterface_da.qm 5 | openterface_de.qm 6 | openterface_en.qm 7 | openterface_fr.qm 8 | openterface_ja.qm 9 | openterface_se.qm 10 | 11 | -------------------------------------------------------------------------------- /config/languages/openterface_da.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/config/languages/openterface_da.qm -------------------------------------------------------------------------------- /config/languages/openterface_de.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/config/languages/openterface_de.qm -------------------------------------------------------------------------------- /config/languages/openterface_en.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/config/languages/openterface_en.qm -------------------------------------------------------------------------------- /config/languages/openterface_fr.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/config/languages/openterface_fr.qm -------------------------------------------------------------------------------- /config/languages/openterface_ja.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/config/languages/openterface_ja.qm -------------------------------------------------------------------------------- /config/languages/openterface_se.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/config/languages/openterface_se.qm -------------------------------------------------------------------------------- /doc/flatpak_installation.md: -------------------------------------------------------------------------------- 1 | ## Prerequisite: Device Permissions Setup 2 | 3 | The OpenterfaceQT app requires access to serial and HID devices. This setup is mandatory for both Flatpak and build-from-source installations. Follow these steps to grant the necessary permissions: 4 | 5 | 1. **Add User to Groups**: 6 | 7 | - Open a terminal and run the following commands: 8 | 9 | ```bash 10 | sudo usermod -aG dialout $USER 11 | sudo usermod -aG plugdev $USER 12 | ``` 13 | 14 | 2. **Create udev Rule for HIDRAW and ttyUSB**: 15 | 16 | - Create a new file `/etc/udev/rules.d/51-openterface.rules` with the following content: 17 | 18 | ```bash 19 | echo 'SUBSYSTEM=="hidraw", ATTRS{idVendor}=="534d", ATTRS{idProduct}=="2109", TAG+="uaccess"' | sudo tee /etc/udev/rules.d/51-openterface.rules 20 | echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="534d", ATTRS{idProduct}=="2109", TAG+="uaccess"' | sudo tee -a /etc/udev/rules.d/51-openterface.rules 21 | echo 'SUBSYSTEM=="ttyUSB", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", TAG+="uaccess"' | sudo tee -a /etc/udev/rules.d/51-openterface.rules 22 | echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", TAG+="uaccess"' | sudo tee -a /etc/udev/rules.d/51-openterface.rules 23 | ``` 24 | 25 | 3. **Reload udev Rules**: 26 | 27 | - Run the following command to reload the udev rules: 28 | 29 | ```bash 30 | sudo udevadm control --reload-rules 31 | sudo udevadm trigger 32 | ``` 33 | 34 | 4. **Apply Changes**: 35 | 36 | - Log out and log back in for the changes to take effect. 37 | 38 | ## Use Flatpak Install 39 | 40 | ### Download Flatpak 41 | 42 | ```sh 43 | sudo apt install -y flatpak flatpak-builder qemu-user-static 44 | # if you are using aarch64, maybe you need to install the following packages: 45 | sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu 46 | ``` 47 | 48 | ### Set up Flatpak Environment 49 | 50 | ```sh 51 | flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo 52 | # if you are using aarch64, maybe you need to install the following packages: 53 | flatpak install --user --noninteractive flathub org.kde.Sdk/aarch64/6.7 54 | flatpak install --user --noninteractive flathub org.kde.Platform/aarch64/6.7 55 | 56 | # if you are using x86_64, maybe you need to install the following packages: 57 | flatpak install --user --noninteractive flathub org.kde.Sdk/x86_64/6.7 58 | flatpak install --user --noninteractive flathub org.kde.Platform/x86_64/6.7 59 | ``` 60 | 61 | ### Download Openterface Flatpak File 62 | 63 | Download the latest version of the Flatpak file. 64 | 65 | ```sh 66 | # This command installs for the user and may prompt you to install some packages; proceed with the installation. 67 | flatpak --user install com.openterface.openterfaceQT-aarch64.flatpak 68 | flatpak --user install com.openterface.openterfaceQT-x86_64.flatpak 69 | # Run the OpenterfaceQT app via Flatpak 70 | flatpak --user run com.openterface.openterfaceQT 71 | ``` 72 | 73 | ### Download Openterface from flathub 74 | 75 | ```sh 76 | flatpak install flathub com.openterface.openterfaceQT 77 | ``` 78 | 79 | ***After you can run the app, enjoy using the OpenterfaceQT app.*** -------------------------------------------------------------------------------- /doc/keyboard_layout_adding.md: -------------------------------------------------------------------------------- 1 | # Keyboard Layout Configuration Guide 2 | 3 | This document provides detailed instructions on how to add and configure new keyboard layouts in the openterfaceQt. 4 | 5 | ## File Structure 6 | 7 | Keyboard layout configuration consists of two main components: 8 | 1. Resource configuration file 9 | 2. Keyboard layout JSON file 10 | 11 | ### Resource Configuration File 12 | 13 | All keyboard layout files must be registered in the name: "keyboard_layouts.qrc" path: "Openterface_QT\config\keyboards\keyboard_layouts.qrc" file: 14 | 15 | ```xml 16 | 17 | 18 | 19 | your_keyboard_layout.json 20 | 21 | 22 | ``` 23 | 24 | ### Keyboard Layout JSON File 25 | 26 | Keyboard layout files (`.json`) should be stored in the `config/keyboards` directory and follow this structure: 27 | 28 | ```json 29 | { 30 | "name": "Display name of the keyboard layout", 31 | "right_to_left": false, 32 | "key_map": {}, 33 | "char_mapping": {}, 34 | "unicode_map": {}, 35 | "need_shift_keys": [], 36 | "need_altgr_keys": [] 37 | } 38 | ``` 39 | 40 | ## Configuration Details 41 | 42 | ### 1. Basic Information 43 | - `name`: The name of the keyboard layout displayed in the software interface. 44 | - `right_to_left`: Indicates whether the layout is for a right-to-left writing system. 45 | 46 | ### 2. Key Mapping (`key_map`) 47 | Defines the mapping between Qt keys and HID codes: 48 | ```json 49 | "key_map": { 50 | "Key_A": "0x04", 51 | "Key_B": "0x05" 52 | } 53 | ``` 54 | 55 | ### 3. Character Mapping (`char_mapping`) 56 | Defines the mapping between characters and Qt keys: 57 | ```json 58 | "char_mapping": { 59 | "a": "Key_A", 60 | "A": "Key_A" 61 | } 62 | ``` 63 | 64 | ### 4. Unicode Mapping (`unicode_map`) 65 | Maps special (non-qtKey) Unicode characters to HID codes: 66 | ```json 67 | "unicode_map": { 68 | "U+20AC": "0x08", // € symbol 69 | "U+00B5": "0x10" // µ symbol 70 | } 71 | ``` 72 | 73 | ### 5. Special Key Configurations 74 | - `need_shift_keys`: A list of characters that require the Shift key to be pressed. 75 | - `need_altgr_keys`: A list of characters that require the AltGr key to be pressed. 76 | 77 | ## Example File 78 | 79 | Refer to name: "qwertz_de.json" path: "Openterface_QT\config\keyboards\qwertz_de.json" for a complete implementation of the German QWERTZ keyboard layout. 80 | 81 | ## Notes 82 | 83 | 1. All HID codes must be in hexadecimal format (starting with `0x`). 84 | 2. Ensure all necessary mappings are defined. 85 | 3. Unicode mapping is only for non-qtKey characters. 86 | 4. Special key configurations must include all characters requiring key combinations. 87 | 88 | ## Validation Steps 89 | 90 | 1. Ensure the JSON file format is correct. 91 | 2. Verify that all required mappings are included. 92 | 3. Test the input of special characters. 93 | 4. Confirm that key combinations work as expected. -------------------------------------------------------------------------------- /docker/Dockerfile.alpine: -------------------------------------------------------------------------------- 1 | FROM alpine:3.19 2 | 3 | # 安装基本构建工具和交叉编译器 4 | RUN apk add --no-cache \ 5 | build-base \ 6 | cmake \ 7 | ninja \ 8 | pkgconfig \ 9 | python3 \ 10 | git \ 11 | curl \ 12 | unzip \ 13 | bison \ 14 | flex \ 15 | autoconf \ 16 | automake \ 17 | libtool \ 18 | linux-headers \ 19 | yasm \ 20 | nasm \ 21 | zip \ 22 | perl \ 23 | libxslt \ 24 | openssl-dev \ 25 | pulseaudio-dev \ 26 | # Qt依赖项 27 | fontconfig-dev \ 28 | freetype-dev \ 29 | mesa-dev \ 30 | eudev-dev \ 31 | libinput-dev \ 32 | libxkbcommon-dev \ 33 | glib-dev \ 34 | vulkan-headers 35 | 36 | # 添加ARM64依赖的仓库 37 | RUN echo "https://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories && \ 38 | echo "https://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \ 39 | apk update 40 | 41 | # 安装交叉编译工具链 42 | RUN apk add --no-cache alpine-sdk && \ 43 | apk add --no-cache \ 44 | gcc-aarch64-none-elf \ 45 | g++-aarch64-none-elf \ 46 | musl-dev 47 | 48 | # 设置工作目录 49 | WORKDIR /opt/build 50 | 51 | # 设置环境变量 52 | ENV CROSS_COMPILE=aarch64-none-elf- \ 53 | CC=aarch64-none-elf-gcc \ 54 | CXX=aarch64-none-elf-g++ \ 55 | PKG_CONFIG_PATH=/usr/aarch64-none-elf/lib/pkgconfig \ 56 | CFLAGS="-Os -ffunction-sections -fdata-sections" \ 57 | CXXFLAGS="-Os -ffunction-sections -fdata-sections" \ 58 | LDFLAGS="-Wl,--gc-sections" 59 | 60 | # 复制构建脚本 61 | COPY build-arm64-qt-alpine.sh /opt/build/ 62 | RUN chmod +x /opt/build/build-arm64-qt-alpine.sh 63 | 64 | CMD ["/opt/build/build-arm64-qt-alpine.sh"] 65 | -------------------------------------------------------------------------------- /docker/Dockerfile.raspbian: -------------------------------------------------------------------------------- 1 | FROM arm32v7/debian:bookworm 2 | 3 | ENV QT_VERSION=6.5.3 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | build-essential \ 7 | cmake \ 8 | git \ 9 | wget \ 10 | libfontconfig1-dev \ 11 | libfreetype6-dev \ 12 | libx11-dev \ 13 | libxext-dev \ 14 | libxfixes-dev \ 15 | libxi-dev \ 16 | libxrender-dev \ 17 | libxcb1-dev \ 18 | libx11-xcb-dev \ 19 | libxcb-glx0-dev \ 20 | libxkbcommon-dev \ 21 | libxkbcommon-x11-dev \ 22 | libglib2.0-dev \ 23 | libgl1-mesa-dev \ 24 | libglu1-mesa-dev \ 25 | freeglut3-dev \ 26 | libegl1-mesa-dev \ 27 | libdbus-1-dev \ 28 | libssl-dev \ 29 | libicu-dev \ 30 | && rm -rf /var/lib/apt/lists/* 31 | 32 | # Download and compile Qt 33 | RUN wget https://download.qt.io/official_releases/qt/6.5/${QT_VERSION}/single/qt-everywhere-src-${QT_VERSION}.tar.xz \ 34 | && tar xf qt-everywhere-src-${QT_VERSION}.tar.xz \ 35 | && cd qt-everywhere-src-${QT_VERSION} \ 36 | && ./configure -prefix /opt/Qt/${QT_VERSION} -opensource -confirm-license -release -nomake examples -nomake tests \ 37 | && make -j$(nproc) \ 38 | && make install \ 39 | && cd .. \ 40 | && rm -rf qt-everywhere-src-${QT_VERSION} qt-everywhere-src-${QT_VERSION}.tar.xz 41 | 42 | # Set Qt environment variables 43 | ENV PATH="/opt/Qt/${QT_VERSION}/bin:${PATH}" 44 | ENV QT_PLUGIN_PATH="/opt/Qt/${QT_VERSION}/plugins" 45 | ENV QML2_IMPORT_PATH="/opt/Qt/${QT_VERSION}/qml" 46 | ENV LD_LIBRARY_PATH="/opt/Qt/${QT_VERSION}/lib:${LD_LIBRARY_PATH}" 47 | 48 | WORKDIR /app 49 | 50 | COPY . . 51 | 52 | RUN cmake -B build -S . -DCMAKE_PREFIX_PATH="/opt/Qt/${QT_VERSION}" && \ 53 | cmake --build build -j$(nproc) 54 | 55 | CMD ["/app/build/openterfaceQT"] 56 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # OpenTerface Alpine QT ARM64 Builder 2 | 3 | This directory contains Docker configurations for building Qt for ARM64 architecture using Alpine Linux. 4 | 5 | ## Authentication with GitHub Container Registry 6 | 7 | Before you can push images to GitHub Container Registry (ghcr.io), you need to authenticate properly. The 403 Forbidden error indicates that there's an issue with authentication or permissions. 8 | 9 | ### Step 1: Create a GitHub Personal Access Token (PAT) 10 | 11 | 1. Go to your GitHub account settings → Developer settings → Personal access tokens 12 | 2. Click on "Generate new token" (classic) 13 | 3. Give it a descriptive name like "OpenTerface Docker Push" 14 | 4. Select the following scopes: 15 | - `repo` (Full control of private repositories) 16 | - `write:packages` (Upload packages to GitHub Package Registry) 17 | - `read:packages` (Download packages from GitHub Package Registry) 18 | 5. Click "Generate token" 19 | 6. **Important:** Copy the token immediately and keep it safe - you won't be able to see it again! 20 | 21 | ### Step 2: Login to GitHub Container Registry 22 | 23 | Use your token to authenticate with GitHub Container Registry: 24 | 25 | ```bash 26 | export GITHUB_TOKEN=your_github_personal_access_token 27 | export GITHUB_USERNAME=your_github_username 28 | echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin 29 | ``` 30 | 31 | ### Step 3: Build and Push the Image 32 | 33 | Use the provided script: 34 | 35 | ```bash 36 | chmod +x build-and-push.sh 37 | ./build-and-push.sh 38 | ``` 39 | 40 | Or manually: 41 | 42 | ```bash 43 | docker buildx create --use --name openterface-builder --driver docker-container 44 | docker buildx build --platform linux/arm64 \ 45 | -t ghcr.io/kevinzjpeng/openterface-alpine-qt-arm64-builder:6.6.3-alpine \ 46 | -f Dockerfile.alpine \ 47 | --push \ 48 | . 49 | ``` 50 | 51 | ## Common Issues 52 | 53 | ### 403 Forbidden Error 54 | 55 | If you encounter a "403 Forbidden" error when pushing to ghcr.io: 56 | 57 | 1. Ensure your Personal Access Token has the correct scopes (write:packages) 58 | 2. Verify that you're properly authenticated with `docker login ghcr.io` 59 | 3. Check if you have the necessary permissions to push to the repository 60 | 4. Make sure the repository exists and is properly configured to accept packages 61 | 62 | ### Repository Visibility 63 | 64 | By default, GitHub packages inherit the visibility of their repository. If you're pushing to a repository that doesn't exist yet, make sure to create it first or adjust the visibility settings. 65 | 66 | ## Reference 67 | 68 | - [GitHub Container Registry Documentation](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) 69 | - [Pushing and pulling Docker images](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#pushing-container-images) 70 | -------------------------------------------------------------------------------- /docker/build-alpine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Create output directory 5 | mkdir -p ./output 6 | # Ensure output directory has correct permissions 7 | chmod 777 ./output 8 | 9 | echo "Starting Alpine ARM64 Qt Docker container build..." 10 | docker-compose -f docker-compose.alpine.yml build 11 | 12 | echo "Starting Alpine ARM64 Qt build process..." 13 | docker-compose -f docker-compose.alpine.yml up 14 | 15 | echo "Build complete!" 16 | echo "Alpine Qt ARM64 build artifacts are in the ./output directory" 17 | -------------------------------------------------------------------------------- /docker/build-and-push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Configuration 5 | IMAGE_NAME="ghcr.io/kevinzjpeng/openterface-alpine-qt-arm64-builder" 6 | VERSION="6.6.3-alpine" 7 | DOCKERFILE="Dockerfile.alpine" 8 | CONTEXT_PATH="." 9 | 10 | # Colors for output 11 | RED='\033[0;31m' 12 | GREEN='\033[0;32m' 13 | YELLOW='\033[0;33m' 14 | NC='\033[0m' # No Color 15 | 16 | # Check if GitHub token is set 17 | if [ -z "$GITHUB_TOKEN" ]; then 18 | echo -e "${YELLOW}Warning: GITHUB_TOKEN environment variable is not set.${NC}" 19 | echo -e "${YELLOW}You will need to be logged in to GitHub Container Registry already.${NC}" 20 | echo -e "${YELLOW}If you're not logged in, the push will fail.${NC}" 21 | echo "" 22 | echo -e "${YELLOW}To log in, you can run:${NC}" 23 | echo -e "${YELLOW} echo \$GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin${NC}" 24 | echo "" 25 | echo -e "${YELLOW}Alternatively, set the GITHUB_TOKEN environment variable:${NC}" 26 | echo -e "${YELLOW} export GITHUB_TOKEN=your_github_personal_access_token${NC}" 27 | echo "" 28 | read -p "Continue anyway? (y/n) " -n 1 -r 29 | echo "" 30 | if [[ ! $REPLY =~ ^[Yy]$ ]]; then 31 | echo "Aborted." 32 | exit 1 33 | fi 34 | else 35 | echo -e "${GREEN}Authenticating with GitHub Container Registry...${NC}" 36 | echo "$GITHUB_TOKEN" | docker login ghcr.io -u "$GITHUB_USERNAME" --password-stdin 37 | fi 38 | 39 | # Build the Docker image 40 | echo -e "${GREEN}Building Docker image: ${IMAGE_NAME}:${VERSION}...${NC}" 41 | docker buildx create --use --name openterface-builder --driver docker-container 42 | 43 | docker buildx build --platform linux/arm64 \ 44 | -t "${IMAGE_NAME}:${VERSION}" \ 45 | -t "${IMAGE_NAME}:latest" \ 46 | -f "${DOCKERFILE}" \ 47 | --push \ 48 | "${CONTEXT_PATH}" 49 | 50 | # Check if the build was successful 51 | if [ $? -eq 0 ]; then 52 | echo -e "${GREEN}Successfully built and pushed ${IMAGE_NAME}:${VERSION}${NC}" 53 | else 54 | echo -e "${RED}Failed to build or push Docker image.${NC}" 55 | echo -e "${YELLOW}If the error was related to authentication, make sure:${NC}" 56 | echo -e "${YELLOW}1. You have a GitHub Personal Access Token with 'write:packages' scope${NC}" 57 | echo -e "${YELLOW}2. You're properly authenticated with 'docker login ghcr.io'${NC}" 58 | echo -e "${YELLOW}3. You have permission to push to the ${IMAGE_NAME} repository${NC}" 59 | exit 1 60 | fi 61 | 62 | # Information about using the built image 63 | echo -e "${GREEN}=== Image Information ===${NC}" 64 | echo -e "Image: ${IMAGE_NAME}:${VERSION}" 65 | echo -e "To pull this image: docker pull ${IMAGE_NAME}:${VERSION}" 66 | echo -e "${GREEN}=========================${NC}" 67 | -------------------------------------------------------------------------------- /docker/build-app-alpine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Set build environment variables for ARM64 Alpine 5 | export ARCH=aarch64 6 | export CROSS_COMPILE=aarch64-alpine-linux-musl- 7 | export PKG_CONFIG_PATH=/usr/aarch64-alpine-linux-musl/lib/pkgconfig 8 | export CC=${CROSS_COMPILE}gcc 9 | export CXX=${CROSS_COMPILE}g++ 10 | export LD=${CROSS_COMPILE}ld 11 | export AR=${CROSS_COMPILE}ar 12 | export STRIP=${CROSS_COMPILE}strip 13 | export QT_INSTALL_DIR=${QT_INSTALL_DIR:-/opt/Qt6-arm64} 14 | export SOURCE_DIR=${SOURCE_DIR:-/app} 15 | export BUILD_DIR=${BUILD_DIR:-/app/build} 16 | 17 | # Create build directory 18 | mkdir -p $BUILD_DIR 19 | 20 | # Create toolchain file 21 | cat > $BUILD_DIR/toolchain.cmake << EOF 22 | set(CMAKE_SYSTEM_NAME Linux) 23 | set(CMAKE_SYSTEM_PROCESSOR aarch64) 24 | set(CMAKE_C_COMPILER $CC) 25 | set(CMAKE_CXX_COMPILER $CXX) 26 | set(CMAKE_FIND_ROOT_PATH /usr/aarch64-alpine-linux-musl) 27 | set(CMAKE_SYSROOT /usr/aarch64-alpine-linux-musl) 28 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 29 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 30 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 31 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 32 | EOF 33 | 34 | # Change to build directory 35 | cd $BUILD_DIR 36 | 37 | # Configure ARM64 build 38 | echo "Configuring Alpine ARM64 build..." 39 | cmake -S "$SOURCE_DIR" -B . \ 40 | -DCMAKE_BUILD_TYPE=MinSizeRel \ 41 | -DBUILD_SHARED_LIBS=OFF \ 42 | -DCMAKE_PREFIX_PATH="$QT_INSTALL_DIR" \ 43 | -DCMAKE_INSTALL_PREFIX=release \ 44 | -DCMAKE_CXX_FLAGS="-Os -ffunction-sections -fdata-sections" \ 45 | -DCMAKE_C_FLAGS="-Os -ffunction-sections -fdata-sections" \ 46 | -DCMAKE_EXE_LINKER_FLAGS="-Wl,--gc-sections -Wl,--strip-all" \ 47 | -DCMAKE_POLICY_DEFAULT_CMP0177=NEW \ 48 | -DCMAKE_POLICY_DEFAULT_CMP0174=NEW \ 49 | -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \ 50 | -DCMAKE_TOOLCHAIN_FILE=$BUILD_DIR/toolchain.cmake \ 51 | -DQT_DEBUG_FIND_PACKAGE=ON 52 | 53 | # Build application 54 | echo "Building application..." 55 | cmake --build . --verbose 56 | 57 | if [ ! -f openterfaceQT ]; then 58 | echo "Error: Failed to build openterfaceQT" 59 | exit 1 60 | fi 61 | 62 | # Strip binary file 63 | echo "Stripping binary file..." 64 | $STRIP --strip-all openterfaceQT 65 | 66 | # Add UPX compression (if available) 67 | if command -v upx >/dev/null 2>&1; then 68 | echo "Compressing executable with UPX..." 69 | upx --best --lzma openterfaceQT 70 | else 71 | echo "UPX not available, skipping compression step..." 72 | fi 73 | 74 | # Create output directory 75 | mkdir -p /app/output 76 | cp openterfaceQT /app/output/ 77 | 78 | # Display final file size 79 | echo "Final executable size:" 80 | ls -lh /app/output/openterfaceQT 81 | 82 | # Set correct permissions 83 | chmod 755 /app/output/openterfaceQT 84 | -------------------------------------------------------------------------------- /docker/docker-compose.alpine.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | qt-alpine-builder: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile.alpine 8 | args: 9 | QT_VERSION: ${QT_VERSION:-6.6.3} 10 | volumes: 11 | - qt-alpine-cache:/opt/output 12 | command: /opt/build/build-arm64-qt-alpine.sh 13 | environment: 14 | - QT_VERSION=${QT_VERSION:-6.6.3} 15 | 16 | app-alpine-builder: 17 | build: 18 | context: . 19 | dockerfile: Dockerfile.alpine 20 | volumes: 21 | - ..:/app 22 | - qt-alpine-cache:/opt/Qt6-arm64 23 | command: /opt/build/build-app-alpine.sh 24 | environment: 25 | - QT_INSTALL_DIR=/opt/Qt6-arm64 26 | - SOURCE_DIR=/app 27 | - BUILD_DIR=/app/build 28 | depends_on: 29 | - qt-alpine-builder 30 | 31 | volumes: 32 | qt-alpine-cache: 33 | driver: local 34 | -------------------------------------------------------------------------------- /driver/linux/Makefile: -------------------------------------------------------------------------------- 1 | CONFIG_MODULE_SIG=n 2 | 3 | ifeq ($(KERNELRELEASE), ) 4 | KERNELDIR := /lib/modules/$(shell uname -r)/build 5 | PWD :=$(shell pwd) 6 | default: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) 8 | clean: 9 | rm -rf *.mk .tmp_versions Module.symvers *.mod.c *.o *.ko .*.cmd Module.markers modules.order *.a *.mod 10 | load: 11 | insmod ch341.ko 12 | unload: 13 | rmmod ch341 14 | install: default 15 | rmmod ch341 || true 16 | insmod ch341.ko || true 17 | mkdir -p /lib/modules/$(shell uname -r)/kernel/drivers/usb/serial/ || true 18 | cp -f ./ch341.ko /lib/modules/$(shell uname -r)/kernel/drivers/usb/serial/ || true 19 | depmod -a 20 | uninstall: 21 | rmmod ch341 || true 22 | rm -rf /lib/modules/$(shell uname -r)/kernel/drivers/usb/serial/ch341.ko || true 23 | depmod -a 24 | else 25 | obj-m := ch341.o 26 | endif 27 | -------------------------------------------------------------------------------- /driver/linux/README.md: -------------------------------------------------------------------------------- 1 | # ch341 linux serial driver 2 | ## Description 3 | 4 | USB serial driver for USB to UART chip ch340, ch341, etc. ch341 supports multiple working modes, this driver only supports its serial port mode. 5 | 6 | In fact the ch341 serial driver has been built-in since the Linux mainline kernel version 2.6.24. The location is: drivers/usb/serial/ch341.c, it's a pity that the built-in driver cannot be kept up to date and cannot support all features of the chip. We suggest our customers to use this driver. 7 | 8 | 1. Open "Terminal" 9 | 2. Switch to "driver" directory 10 | 3. Compile the driver using "make", you will see the module "ch341.ko" if successful 11 | 4. Type "sudo make load" or "sudo insmod ch341.ko" to load the driver dynamically 12 | 5. Type "sudo make unload" or "sudo rmmod ch341.ko" to unload the driver 13 | 6. Type "sudo make install" to make the driver work permanently 14 | 7. Type "sudo make uninstall" to remove the driver 15 | 8. You can refer to the link below to acquire uart application, you can use gcc or Cross-compile with cross-gcc 16 | https://github.com/WCHSoftGroup/tty_uart 17 | 18 | Before the driver works, you should make sure that the usb device has been plugged in and is working properly, you can use shell command "lsusb" or "dmesg" to confirm that, USB VID of these devices are [1a86], you can view all IDs from the id table which defined in "ch341.c". 19 | 20 | If the device works well, the driver will created tty devices named "ttyCH341USBx" in /dev directory. 21 | 22 | ## Note 23 | 24 | Any question, you can send feedback to mail: tech@wch.cn 25 | -------------------------------------------------------------------------------- /driver/linux/drivers.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch341.c 5 | ch341.h 6 | Makefile 7 | 8 | -------------------------------------------------------------------------------- /driver/windows/CH341PORTSA64.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/driver/windows/CH341PORTSA64.DLL -------------------------------------------------------------------------------- /driver/windows/CH341PT.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/driver/windows/CH341PT.DLL -------------------------------------------------------------------------------- /driver/windows/CH341PTA64.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/driver/windows/CH341PTA64.DLL -------------------------------------------------------------------------------- /driver/windows/CH341SER.CAT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/driver/windows/CH341SER.CAT -------------------------------------------------------------------------------- /driver/windows/CH341SER.INF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/driver/windows/CH341SER.INF -------------------------------------------------------------------------------- /driver/windows/ch341ser.PNF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/driver/windows/ch341ser.PNF -------------------------------------------------------------------------------- /driver/windows/drivers.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CH341SER.INF 5 | 6 | -------------------------------------------------------------------------------- /host/audiomanager.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIOMANAGER_H 2 | #define AUDIOMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class AudioThread; 11 | 12 | Q_DECLARE_LOGGING_CATEGORY(log_core_host_audio) 13 | 14 | class AudioManager : public QObject { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit AudioManager(QObject *parent = nullptr); 19 | ~AudioManager(); 20 | 21 | void initializeAudio(); 22 | void disconnect(); 23 | 24 | private slots: 25 | void handleAudioError(const QString& error); 26 | 27 | private: 28 | QAudioDevice findUvcCameraAudioDevice(QString deviceName); 29 | QAudioDevice findSystemAudioOuptutDevice(QString deviceName); 30 | void fadeInVolume(int timeout, int durationInSeconds); 31 | 32 | AudioThread* m_audioThread; 33 | }; 34 | 35 | #endif // AUDIOMANAGER_H 36 | -------------------------------------------------------------------------------- /host/audiothread.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIOTHREAD_H 2 | #define AUDIOTHREAD_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class AudioThread : public QThread { 12 | Q_OBJECT 13 | 14 | public: 15 | AudioThread(const QAudioDevice& inputDevice, 16 | const QAudioDevice& outputDevice, 17 | const QAudioFormat& format, 18 | QObject* parent = nullptr); 19 | ~AudioThread(); 20 | 21 | void stop(); 22 | void setVolume(qreal volume); 23 | qreal volume() const; 24 | 25 | signals: 26 | void error(const QString& message); 27 | 28 | protected: 29 | void run() override; 30 | 31 | private: 32 | QAudioDevice m_inputDevice; 33 | QAudioDevice m_outputDevice; 34 | QAudioFormat m_format; 35 | QAudioSource* m_audioSource; 36 | QScopedPointer m_audioSink; 37 | QIODevice* m_audioIODevice; // For reading from source 38 | QIODevice* m_sinkIODevice; // For writing to sink 39 | bool m_running; 40 | mutable QMutex m_mutex; // Make the mutex mutable so it can be locked in const functions 41 | qreal m_volume; 42 | }; 43 | 44 | #endif // AUDIOTHREAD_H 45 | -------------------------------------------------------------------------------- /host/cameramanager.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERAMANAGER_H 2 | #define CAMERAMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include // Add this include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | // Struct to represent a video format key, used for comparing and sorting video formats 19 | // It includes resolution, frame rate range, and pixel format 20 | struct VideoFormatKey { 21 | QSize resolution; 22 | int minFrameRate; 23 | int maxFrameRate; 24 | QVideoFrameFormat::PixelFormat pixelFormat; 25 | 26 | bool operator<(const VideoFormatKey &other) const { 27 | if (resolution.width() != other.resolution.width()) 28 | return resolution.width() < other.resolution.width(); 29 | if (resolution.height() != other.resolution.height()) 30 | return resolution.height() < other.resolution.height(); 31 | if (minFrameRate != other.minFrameRate) 32 | return minFrameRate < other.minFrameRate; 33 | if (maxFrameRate != other.maxFrameRate) 34 | return maxFrameRate < other.maxFrameRate; 35 | return pixelFormat < other.pixelFormat; 36 | } 37 | }; 38 | 39 | 40 | class CameraManager : public QObject 41 | { 42 | Q_OBJECT 43 | 44 | public: 45 | explicit CameraManager(QObject *parent = nullptr); 46 | ~CameraManager(); 47 | 48 | void setCamera(const QCameraDevice &cameraDevice, QVideoWidget* videoOutput); 49 | void setCameraDevice(const QCameraDevice &cameraDevice); 50 | void startCamera(); 51 | void stopCamera(); 52 | void takeImage(const QString& file); 53 | void takeAreaImage(const QString& file, const QRect& captureArea); 54 | void startRecording(); 55 | void stopRecording(); 56 | QCamera* getCamera() const { return m_camera.get(); } 57 | void setVideoOutput(QVideoWidget* videoOutput); 58 | void setCameraFormat(const QCameraFormat &format); 59 | QCameraFormat getCameraFormat() const; 60 | QList getCameraFormats() const; 61 | void loadCameraSettingAndSetCamera(); 62 | void queryResolutions(); 63 | void configureResolutionAndFormat(); 64 | std::map getVideoFormatMap(); 65 | 66 | // Updated method to return supported pixel formats 67 | QList getSupportedPixelFormats() const; 68 | QCameraFormat getVideoFormat(const QSize &resolution, int desiredFrameRate, QVideoFrameFormat::PixelFormat pixelFormat) const; 69 | 70 | signals: 71 | void cameraActiveChanged(bool active); 72 | void cameraSettingsApplied(); 73 | void recordingStarted(); 74 | void recordingStopped(); 75 | void cameraError(const QString &errorString); 76 | void resolutionsUpdated(int input_width, int input_height, float input_fps, int capture_width, int capture_height, int capture_fps, float pixelClk); 77 | void imageCaptured(int id, const QImage& img); 78 | void lastImagePath(const QString& imagePath); 79 | 80 | private slots: 81 | void onImageCaptured(int id, const QImage& img); 82 | 83 | private: 84 | std::unique_ptr m_camera; 85 | QMediaCaptureSession m_captureSession; 86 | std::unique_ptr m_imageCapture; 87 | std::unique_ptr m_mediaRecorder; 88 | QVideoWidget* m_videoOutput; 89 | int m_video_width; 90 | int m_video_height; 91 | QString filePath; 92 | void setupConnections(); 93 | 94 | QRect copyRect; 95 | std::map videoFormatMap; 96 | }; 97 | 98 | #endif // CAMERAMANAGER_H 99 | -------------------------------------------------------------------------------- /images/capture.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/content_dark_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/content_dark_eng.png -------------------------------------------------------------------------------- /images/contrast.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | -------------------------------------------------------------------------------- /images/full_screen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | zoom 6 | Created with Sketch Beta. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /images/icon_128.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/icon_128.ico -------------------------------------------------------------------------------- /images/icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/icon_128.png -------------------------------------------------------------------------------- /images/icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/icon_256.png -------------------------------------------------------------------------------- /images/icon_32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/icon_32.ico -------------------------------------------------------------------------------- /images/icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/icon_32.png -------------------------------------------------------------------------------- /images/icon_64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/icon_64.ico -------------------------------------------------------------------------------- /images/icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/images/icon_64.png -------------------------------------------------------------------------------- /images/keyboard-pressed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /images/keyboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 35 | -------------------------------------------------------------------------------- /images/mouse-default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/mouse-left-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 16 | 17 | -------------------------------------------------------------------------------- /images/mouse-middle-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/mouse-right-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 16 | 17 | -------------------------------------------------------------------------------- /images/paste.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 16 | 18 | 20 | 22 | 24 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /images/screen_scale.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/screensaver.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /images/shutter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 14 | 16 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /images/zoom_fit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/zoom_in.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/zoom_out.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /installer.iss: -------------------------------------------------------------------------------- 1 | ; Script generated by the Inno Setup Script Wizard. 2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! 3 | 4 | #define MyAppName "Openterface Mini-KVM" 5 | ; #define MyAppExeName "openterfaceQT.exe" 6 | 7 | #pragma message "AppVersion: " + MyAppVersion 8 | #pragma message "MyAppPublisher: " + MyAppPublisher 9 | #pragma message "MyAppURL: " + MyAppURL 10 | 11 | [Setup] 12 | ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. 13 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) 14 | AppId={{4200459F-8F27-46C4-BFB2-65C1447AE912} 15 | AppName={#MyAppName} 16 | AppVersion={#MyAppVersion} 17 | ;AppVerName={#MyAppName} {#MyAppVersion} 18 | VersionInfoProductTextVersion={#MyAppVersion} 19 | AppPublisher={#MyAppPublisher} 20 | AppPublisherURL={#MyAppURL} 21 | AppSupportURL={#MyAppURL} 22 | AppUpdatesURL={#MyAppURL} 23 | AppCopyright=Copyright © All rights reserved. 2024 TechxArtisan Limited 24 | LicenseFile={#SourcePackage}\LICENSE 25 | DefaultDirName={autopf}\{#MyAppName} 26 | DisableProgramGroupPage=yes 27 | VersionInfoVersion={#MyAppVersion} 28 | VersionInfoDescription={#MyAppName} {#MyAppVersion} Installer 29 | VersionInfoCompany={#MyAppPublisher} 30 | VersionInfoCopyright=Copyright © {#MyAppPublisher} {#MyAppVersion} 31 | ; Uncomment the following line to run in non administrative install mode (install for current user only.) 32 | ;PrivilegesRequired=lowest 33 | ; OutputBaseFilename=setup 34 | OutputDir={#OutputDir} 35 | OutputBaseFilename={#OutputBaseFileName} 36 | Compression=lzma2/max 37 | SolidCompression=yes 38 | WizardStyle=modern 39 | SetupLogging=yes 40 | 41 | [Languages] 42 | Name: "english"; MessagesFile: "compiler:Default.isl" 43 | 44 | [Tasks] 45 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked 46 | 47 | [Files] 48 | Source: "{#SourcePackage}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion 49 | Source: "{#SourcePackage}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs 50 | Source: "{#SourcePackage}\driver\windows\CH341SER.INF"; DestDir: {app}\driver; 51 | Source: "{#SourcePackage}\driver\windows\CH341S64.SYS"; DestDir: {app}\driver; 52 | 53 | 54 | ; NOTE: Don't use "Flags: ignoreversion" on any shared system files 55 | 56 | [Icons] 57 | Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" 58 | Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon 59 | 60 | [Run] 61 | Filename: "{app}\{#MyAppExeName}"; \ 62 | Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \ 63 | Flags: nowait postinstall skipifsilent; \ 64 | Parameters: "/silent" 65 | Filename: {sys}\pnputil.exe; \ 66 | Parameters: "/add-driver CH341SER.INF /install"; \ 67 | WorkingDir: {app}\driver; Flags: 64bit runhidden; -------------------------------------------------------------------------------- /installer.nsi: -------------------------------------------------------------------------------- 1 | ; NSIS script for Openterface Mini-KVM 2 | ; Generated based on the provided Inno Setup script 3 | 4 | !define MyAppName "Openterface Mini-KVM" 5 | !define LicenseFile "LICENSE" 6 | !define SourcePackage "." 7 | 8 | ; Set output file 9 | OutFile "${OutputDir}\${OutputBaseFileName}.exe" 10 | 11 | ; Installer settings 12 | Name "${MyAppName} ${MyAppVersion}" 13 | InstallDir "$PROGRAMFILES\${MyAppName}" 14 | ShowInstDetails show 15 | ShowUninstDetails show 16 | 17 | ; Include license 18 | LicenseData "${SourcePackage}\${LicenseFile}" 19 | 20 | ; Modern UI settings 21 | !include "MUI2.nsh" 22 | !define MUI_ABORTWARNING 23 | !insertmacro MUI_PAGE_WELCOME 24 | !insertmacro MUI_PAGE_LICENSE "${SourcePackage}\${LicenseFile}" 25 | !insertmacro MUI_PAGE_DIRECTORY 26 | !insertmacro MUI_PAGE_INSTFILES 27 | !define MUI_FINISHPAGE_RUN 28 | !define MUI_FINISHPAGE_RUN_TEXT "Run ${MyAppName} now" 29 | !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchApp" 30 | !insertmacro MUI_PAGE_FINISH 31 | !insertmacro MUI_LANGUAGE "English" 32 | 33 | Icon "${SourcePackage}\images\icon_128.ico" 34 | 35 | Section "Install" 36 | ; Create installation directory 37 | SetOutPath "$INSTDIR" 38 | 39 | ; Copy application files 40 | File /r "${WorkingDir}\*" 41 | 42 | ; Create shortcuts 43 | CreateShortcut "$SMPROGRAMS\${MyAppName}.lnk" "$INSTDIR\${MyAppExeName}" 44 | CreateShortcut "$DESKTOP\${MyAppName}.lnk" "$INSTDIR\${MyAppExeName}" 45 | 46 | ; Run the application after installation 47 | Exec "$INSTDIR\${MyAppExeName} /silent" 48 | 49 | ; Write uninstaller 50 | WriteUninstaller "$INSTDIR\Uninstall.exe" 51 | SectionEnd 52 | 53 | Section "Uninstall" 54 | ; Remove application files 55 | Delete "$INSTDIR\*.*" 56 | RMDir /r "$INSTDIR" 57 | 58 | ; Remove shortcuts 59 | Delete "$SMPROGRAMS\${MyAppName}.lnk" 60 | Delete "$DESKTOP\${MyAppName}.lnk" 61 | 62 | ; Uninstall driver 63 | ExecWait '"$SYSDIR\pnputil.exe" /delete-driver CH341SER.INF /uninstall' 64 | 65 | ; Remove installation directory 66 | RMDir /r "$INSTDIR" 67 | SectionEnd 68 | 69 | Function LaunchApp 70 | Exec "$INSTDIR\${MyAppExeName}" 71 | FunctionEnd 72 | -------------------------------------------------------------------------------- /lib/libusb-1.0.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/lib/libusb-1.0.a -------------------------------------------------------------------------------- /lib/libusb-1.0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/lib/libusb-1.0.dll -------------------------------------------------------------------------------- /lib/libusb-1.0.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/lib/libusb-1.0.lib -------------------------------------------------------------------------------- /openterfaceQT.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON ICON DISCARDABLE ".\\images\\icon_128.ico" -------------------------------------------------------------------------------- /packaging/appimage/openterfaceQT.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.openterface.OpenterfaceQT 4 | OpenterfaceQT 5 | A QT-based interface for Openterface 6 | FSFAP 7 | AGPL-3.0 8 | Kevin Peng 9 | 10 | 11 |

12 | OpenterfaceQT is a cross-platform application that provides a modern QT-based 13 | interface for the Openterface project. 14 |

15 |

16 | Key features: 17 |

18 |
    19 |
  • Cross-platform compatibility (Linux, Windows, macOS)
  • 20 |
  • Modern QT6-based user interface
  • 21 |
  • Customizable keyboard layouts
  • 22 |
  • Multi-language support
  • 23 |
24 |
25 | 26 | openterfaceQT.desktop 27 | 28 | 29 | 30 | Main application window 31 | https://openterface.com/images/product/win_qt_app.jpg 32 | 33 | 34 | 35 | https://openterface.com 36 | https://github.com/TechxArtisanStudio/OpenterfaceQT/issues 37 | 38 | 39 | openterfaceQT 40 | 41 | 42 | 43 | 44 | 45 |

Latest version with improvements and bug fixes

46 |
47 |
48 |
49 | 50 | 51 |
52 | -------------------------------------------------------------------------------- /packaging/appimage/openterfaceQT.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Name=OpenterfaceQT 5 | Exec=openterfaceQT 6 | Icon=openterfaceQT 7 | Comment=OpenterfaceQT Application 8 | Categories=Utility; 9 | Terminal=false 10 | StartupNotify=true 11 | -------------------------------------------------------------------------------- /packaging/debian/control: -------------------------------------------------------------------------------- 1 | Package: openterfaceQT 2 | Version: ${VERSION} 3 | Section: base 4 | Priority: optional 5 | Architecture: ${ARCH} 6 | Depends: libqt6core6 (>= 6.4.2), libqt6multimedia6 (>= 6.4.2), libqt6multimediawidgets6 (>= 6.4.2), libqt6serialport6 (>= 6.4.2), libqt6svg6 (>= 6.4.2) 7 | Maintainer: TechxArtisan 8 | Description: OpenterfaceQT Mini-KVM Linux Edition 9 | -------------------------------------------------------------------------------- /packaging/rpm/spec: -------------------------------------------------------------------------------- 1 | Name: openterfaceqt 2 | Version: ${VERSION} 3 | Release: 1 4 | Summary: OpenterfaceQT Mini-KVM Application 5 | 6 | License: AGPL-3.0 7 | URL: https://github.com/kevinzjpeng/Openterface_QT 8 | 9 | %if 0%{?fedora} || 0%{?rhel} 10 | # For Red Hat based systems 11 | Requires: qt6-qtbase qt6-qtbase-gui qt6-qtmultimedia qt6-qtserialport qt6-qtsvg libusb 12 | %endif 13 | 14 | %if 0%{?suse_version} 15 | # For SUSE based systems 16 | Requires: libQt6Core6 libQt6DBus6 libQt6Gui6 libQt6Network6 libQt6Multimedia6 libQt6MultimediaWidgets6 libQt6SerialPort6 libQt6Svg6 libusb-1_0 17 | %endif 18 | 19 | %if 0%{?debian} || 0%{?ubuntu} 20 | # For Debian based systems 21 | Requires: libqt6core6 libqt6dbus6 libqt6gui6 libqt6network6 libqt6multimedia6 libqt6multimediawidgets6 libqt6serialport6 libqt6svg6 libusb-1.0-0 22 | %endif 23 | 24 | %description 25 | OpenterfaceQT Application 26 | 27 | %install 28 | mkdir -p %{buildroot}/usr/bin 29 | mkdir -p %{buildroot}/usr/share/icons/hicolor/256x256/apps 30 | mkdir -p %{buildroot}/usr/share/applications 31 | 32 | cp -r %{_sourcedir}/openterfaceQT %{buildroot}/usr/bin/ 33 | cp %{_sourcedir}/icon_256.png %{buildroot}/usr/share/icons/hicolor/256x256/apps/openterfaceQT.png 34 | 35 | cat > %{buildroot}/usr/share/applications/openterfaceQT.desktop << EOF 36 | [Desktop Entry] 37 | Version=${VERSION} 38 | Type=Application 39 | Name=OpenterfaceQT 40 | Exec=/usr/bin/openterfaceQT 41 | Icon=openterfaceQT 42 | Comment=OpenterfaceQT Application 43 | Categories=Utility; 44 | EOF 45 | 46 | 47 | %files 48 | /usr/bin/openterfaceQT 49 | /usr/share/icons/hicolor/256x256/apps/openterfaceQT.png 50 | /usr/share/applications/openterfaceQT.desktop 51 | 52 | %changelog 53 | * Tue Mar 19 2025 Your Name - ${VERSION}-1 54 | - Initial RPM release -------------------------------------------------------------------------------- /qt-installer-noninteractive.qs: -------------------------------------------------------------------------------- 1 | function Controller() { 2 | installer.autoRejectMessageBoxes(); 3 | installer.installationFinished.connect(function() { 4 | gui.clickButton(buttons.NextButton); 5 | }) 6 | } 7 | 8 | Controller.prototype.WelcomePageCallback = function() { 9 | gui.clickButton(buttons.NextButton, 3000); 10 | } 11 | 12 | Controller.prototype.CredentialsPageCallback = function() { 13 | gui.clickButton(buttons.NextButton); 14 | } 15 | 16 | Controller.prototype.IntroductionPageCallback = function() { 17 | gui.clickButton(buttons.NextButton); 18 | } 19 | 20 | Controller.prototype.TargetDirectoryPageCallback = function() 21 | { 22 | gui.currentPageWidget().TargetDirectoryLineEdit.setText("/opt/Qt"); 23 | gui.clickButton(buttons.NextButton); 24 | } 25 | 26 | Controller.prototype.ComponentSelectionPageCallback = function() { 27 | var widget = gui.currentPageWidget(); 28 | widget.deselectAll(); 29 | widget.selectComponent("qt.qt6.642.gcc_64"); 30 | gui.clickButton(buttons.NextButton); 31 | } 32 | 33 | Controller.prototype.LicenseAgreementPageCallback = function() { 34 | gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); 35 | gui.clickButton(buttons.NextButton); 36 | } 37 | 38 | Controller.prototype.StartMenuDirectoryPageCallback = function() { 39 | gui.clickButton(buttons.NextButton); 40 | } 41 | 42 | Controller.prototype.ReadyForInstallationPageCallback = function() 43 | { 44 | gui.clickButton(buttons.NextButton); 45 | } 46 | 47 | Controller.prototype.FinishedPageCallback = function() { 48 | var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm 49 | if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) { 50 | checkBoxForm.launchQtCreatorCheckBox.checked = false; 51 | } 52 | gui.clickButton(buttons.FinishButton); 53 | } 54 | -------------------------------------------------------------------------------- /regex/RegularExpression.cpp: -------------------------------------------------------------------------------- 1 | #include "RegularExpression.h" 2 | 3 | RegularExpression::RegularExpression() { 4 | onRegex = QRegularExpression(QString("^(1|True|On)$"), QRegularExpression::CaseInsensitiveOption); 5 | offRegex = QRegularExpression(QString("^(0|False|Off)$"), QRegularExpression::CaseInsensitiveOption); 6 | sendEmbedRegex = QRegularExpression(QString(R"(\{Click\s*([^}]*)\})"), QRegularExpression::CaseInsensitiveOption); 7 | numberRegex = QRegularExpression(QString(R"(\d+)")); 8 | buttonRegex = QRegularExpression(QString(R"((? 5 | #include 6 | 7 | class RegularExpression { 8 | public: 9 | RegularExpression(const RegularExpression&) = delete; 10 | RegularExpression& operator=(const RegularExpression&) = delete; 11 | 12 | static RegularExpression& instance() { 13 | static RegularExpression instance; 14 | return instance; 15 | } 16 | 17 | QRegularExpression onRegex; 18 | QRegularExpression offRegex; 19 | QRegularExpression sendEmbedRegex; 20 | QRegularExpression numberRegex; 21 | QRegularExpression buttonRegex; 22 | QRegularExpression downUpRegex; 23 | QRegularExpression relativeRegex; 24 | QRegularExpression braceKeyRegex; 25 | QRegularExpression controlKeyRegex; 26 | 27 | private: 28 | RegularExpression(); 29 | ~RegularExpression() = default; 30 | }; 31 | 32 | #endif // REGULAR_EXPRESSIONS_H -------------------------------------------------------------------------------- /resources/version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | // This file defines the application version. 4 | // Major release, Minor release, Patch number, Days since January 1st. 5 | // The patch number resets to 1 whenever the major or minor version is updated. 6 | // Please refer to update_version.py 7 | 8 | #define APP_VERSION "0.3.14.150" 9 | 10 | #endif // VERSION_H 11 | -------------------------------------------------------------------------------- /scripts/AST.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef AST_H 24 | #define AST_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | enum class ASTNodeType { 32 | Expression, 33 | Statement, 34 | CommandStatement, 35 | 36 | StatementList, 37 | // Add more node types as needed 38 | }; 39 | 40 | class ASTNode { 41 | public: 42 | virtual ~ASTNode() = default; 43 | virtual ASTNodeType getType() const = 0; 44 | virtual const std::vector>& getChildren() const { return children; } 45 | protected: 46 | std::vector> children; 47 | }; 48 | 49 | class ExpressionNode : public ASTNode { 50 | public: 51 | ASTNodeType getType() const override { return ASTNodeType::Expression; } 52 | // Add expression-specific members 53 | }; 54 | 55 | class StatementNode : public ASTNode { 56 | public: 57 | ASTNodeType getType() const override { return ASTNodeType::Statement; } 58 | // Add statement-specific members 59 | }; 60 | 61 | class CommandStatementNode : public ASTNode { 62 | public: 63 | CommandStatementNode(const std::vector& options) : options(options) {} 64 | ASTNodeType getType() const override { return ASTNodeType::CommandStatement; } 65 | const std::vector& getOptions() const { return options; } 66 | const QString getCommandName() const { return commandName; } 67 | void setCommandName(QString name) { commandName = name; } 68 | private: 69 | std::vector options; 70 | QString commandName; 71 | }; 72 | 73 | 74 | 75 | class StatementListNode : public ASTNode { 76 | public: 77 | ASTNodeType getType() const override { return ASTNodeType::StatementList; } 78 | void addStatement(std::unique_ptr statement) { 79 | if (statement) { 80 | children.push_back(std::move(statement)); 81 | } 82 | } 83 | }; 84 | 85 | // Add more specific node types as needed 86 | 87 | #endif // AST_H 88 | -------------------------------------------------------------------------------- /scripts/Lexer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef LEXER_H 24 | #define LEXER_H 25 | 26 | #include 27 | #include 28 | #include "Token.h" 29 | 30 | class Lexer { 31 | public: 32 | Lexer(); 33 | void setSource(const std::string& source); 34 | std::vector tokenize(); 35 | 36 | private: 37 | std::string source; 38 | size_t currentIndex; 39 | char currentChar(); 40 | 41 | void advance(); 42 | Token nextToken(); 43 | Token identifier(); 44 | Token number(); 45 | Token symbol(); 46 | }; 47 | 48 | #endif // LEXER_H 49 | -------------------------------------------------------------------------------- /scripts/Parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | #ifndef PARSER_H 25 | #define PARSER_H 26 | 27 | #include 28 | #include "Token.h" 29 | #include "AST.h" 30 | 31 | class Parser { 32 | public: 33 | Parser(const std::vector& tokens); 34 | std::unique_ptr parse(); 35 | 36 | private: 37 | const std::vector& tokens; 38 | size_t currentIndex; 39 | 40 | Token currentToken(); 41 | void advance(); 42 | std::unique_ptr parseExpression(); 43 | std::unique_ptr parseStatement(); 44 | std::unique_ptr parseCommandStatement(); 45 | // std::unique_ptr parseSendStatement(); 46 | // Add more parsing methods as needed 47 | }; 48 | 49 | #endif // PARSER_H 50 | -------------------------------------------------------------------------------- /scripts/Token.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | #ifndef TOKEN_H 25 | #define TOKEN_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | 36 | enum class AHKTokenType { 37 | KEYWORD, 38 | IDENTIFIER, 39 | OBJECT, 40 | INTEGER, 41 | FLOAT, 42 | STRING, 43 | OPERATOR, 44 | SYMBOL, 45 | VARIABLE, 46 | COMMENT, 47 | COMMAND, 48 | WHITESPACE, 49 | FUNCTION, 50 | INVALID, 51 | NEWLINE, 52 | ENDOFFILE 53 | }; 54 | 55 | 56 | struct Token { 57 | AHKTokenType type; 58 | std::string value; 59 | }; 60 | 61 | const std::set keywords = { 62 | "If", "Else", "Loop", "While", "For", "Try", "Catch", "Finally", "Throw", 63 | "Switch", "Return", "Goto", "Continue", "Until" 64 | }; 65 | 66 | const std::vector operators = { 67 | ":=", "=", "+=", "-=", "*=", "/=", ".=", "|=", "&=", "^=", ">>=", "<<=", "+", "++", "-", "--", "*", "**", "/", "//", 68 | ">", "<", "!", "==", "!=", "<>", "|", "||", "&", "&&", 69 | "%", ".", "()", 70 | }; 71 | 72 | const std::set mouse_keyboard = { 73 | "BlockInput", "Click", "ControlClick", "ControlSend", "CoordMode","GetKeyName", "GetKeySC", "GetKeyState", 74 | "GetKeyVK", "List of Keys", "KeyHistory", "KeyWait", "Input", "InputHook", "MouseClick", "MouseClickDrag", 75 | "MouseGetPos", "MouseMove", "Send", "SendLevel", "SendMode", "SetCapsLockState", "SetDefaultMouseSpeed", 76 | "SetKeyDelay", "SetNumLockState", "SetScrollLockState", "SetStoreCapsLockMode", "Sleep", "FullScreenCapture","AreaScreenCapture" 77 | }; 78 | 79 | 80 | #endif // TOKEN_H 81 | -------------------------------------------------------------------------------- /scripts/scriptEditor.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIPTEDITOR_H 2 | #define SCRIPTEDITOR_H 3 | 4 | #include 5 | #include 6 | 7 | class LineNumberArea; 8 | 9 | class ScriptEditor : public QTextEdit 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit ScriptEditor(QWidget *parent = nullptr); 15 | ~ScriptEditor(); 16 | 17 | int lineNumberAreaWidth(); // Public for LineNumberArea 18 | void lineNumberAreaPaintEvent(QPaintEvent *event); // Public for LineNumberArea 19 | void highlightLine(int lineNumber); 20 | void resetHighlightLine(int lineNumber); 21 | 22 | private slots: 23 | void updateLineNumberAreaWidth(); // No parameter needed 24 | 25 | private: 26 | LineNumberArea *lineNumberArea; 27 | int highlightedLineNumber = -1; 28 | 29 | void updateLineNumberArea(const QRect &rect, int dy); 30 | void resizeEvent(QResizeEvent *event) override; 31 | void scrollContentsBy(int dx, int dy) override; // Override to handle scrolling 32 | }; 33 | 34 | class LineNumberArea : public QWidget 35 | { 36 | public: 37 | LineNumberArea(ScriptEditor *editor) : QWidget(editor), scriptEditor(editor) {} 38 | QSize sizeHint() const override { return QSize(scriptEditor->lineNumberAreaWidth(), 0); } 39 | 40 | protected: 41 | void paintEvent(QPaintEvent *event) override { scriptEditor->lineNumberAreaPaintEvent(event); } 42 | 43 | private: 44 | ScriptEditor *scriptEditor; 45 | }; 46 | 47 | #endif // SCRIPTEDITOR_H 48 | -------------------------------------------------------------------------------- /scripts/semanticAnalyzer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | #ifndef SEMANTIC_ANALYZER_H 25 | #define SEMANTIC_ANALYZER_H 26 | 27 | #include "target/MouseManager.h" 28 | #include "regex/RegularExpression.h" 29 | // #include "target/KeyboardManager.h" 30 | #include "KeyboardMouse.h" 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | struct MouseParams{ 38 | uint8_t mode; 39 | uint8_t mouseButton; 40 | uint8_t wheelDelta; 41 | Coordinate coord; 42 | }; 43 | class SemanticAnalyzer : public QObject { 44 | Q_OBJECT 45 | 46 | public: 47 | SemanticAnalyzer(MouseManager* mouseManager, KeyboardMouse* keyboardMouse, QObject* parent = nullptr); 48 | bool analyze(const ASTNode* node); 49 | 50 | 51 | signals: 52 | void captureImg(const QString& path = ""); 53 | void captureAreaImg(const QString& path = "", const QRect& captureArea = QRect()); 54 | void commandIncrease(); 55 | 56 | private: 57 | MouseManager* mouseManager; 58 | KeyboardMouse* keyboardMouse; 59 | void analyzeCommandStetement(const CommandStatementNode* node); 60 | void analyzeClickStatement(const CommandStatementNode* node); 61 | void analyzeSendStatement(const CommandStatementNode* node); 62 | QPoint parseCoordinates(const std::vector& options); 63 | int parseMouseButton(const std::vector& options); 64 | void resetParameters(); 65 | 66 | void analyzeSleepStatement(const CommandStatementNode* node); 67 | void analyzeMouseMove(const CommandStatementNode* node); 68 | void analyzeLockState(const CommandStatementNode* node, const QString& keyName, bool (KeyboardMouse::*getStateFunc)()); 69 | void analyzeFullScreenCapture(const CommandStatementNode* node); 70 | void analyzeAreaScreenCapture(const CommandStatementNode* node); 71 | QString extractFilePath(const QString& originText); 72 | 73 | RegularExpression& regex = RegularExpression::instance(); 74 | MouseParams parserClickParam(const QString& command); 75 | }; 76 | 77 | #endif // SEMANTIC_ANALYZER_H 78 | -------------------------------------------------------------------------------- /serial/TEST: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechxArtisanStudio/Openterface_QT/6b882c724caccbc8628b4086788148968721aad9/serial/TEST -------------------------------------------------------------------------------- /server/tcpServer.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPSERVER_H 2 | #define TCPSERVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../scripts/Lexer.h" 9 | #include "../scripts/Parser.h" 10 | 11 | enum ActionCommand { 12 | CmdUnknow = -1, 13 | CmdGetLastImage, 14 | CheckStatus, 15 | ScriptCommand 16 | }; 17 | 18 | enum ActionStatus{ 19 | Finish, 20 | Running, 21 | Fail 22 | }; 23 | 24 | class TcpServer : public QTcpServer { 25 | Q_OBJECT 26 | 27 | public: 28 | explicit TcpServer(QObject *parent = nullptr); 29 | void startServer(quint16 port); 30 | 31 | signals: 32 | void syntaxTreeReady(std::shared_ptr syntaxTree); 33 | 34 | public slots: 35 | void handleImgPath(const QString& imagePath); 36 | void recvTCPCommandStatus(bool status); 37 | 38 | private slots: 39 | void onNewConnection(); 40 | void onReadyRead(); 41 | 42 | private: 43 | QTcpSocket *currentClient; 44 | QString lastImgPath; 45 | ActionCommand parseCommand(const QByteArray& data); 46 | void sendImageToClient(); 47 | void processCommand(ActionCommand cmd); 48 | Lexer lexer; 49 | std::vector tokens; 50 | QString scriptStatement; 51 | void compileScript(); 52 | ActionStatus actionStatus; 53 | void correponseClientStauts(); 54 | }; 55 | 56 | 57 | #endif // TCPSERVER_H 58 | -------------------------------------------------------------------------------- /target/mouseeventdto.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #include "target/mouseeventdto.h" 24 | 25 | MouseEventDTO::MouseEventDTO(int x, int y, bool isAbsoluteMode, int mouseButton, int wheelDelta) 26 | : absX(x), absY(y), _isAbsoluteMode(isAbsoluteMode) { 27 | if (!isAbsoluteMode) { 28 | // Calculate delta values if not in absolute mode 29 | deltaX = x; // Assuming x is deltaX in relative mode 30 | deltaY = y; // Assuming y is deltaY in relative mode 31 | } 32 | this->mouseButton = mouseButton; 33 | this->wheelDelta = wheelDelta; 34 | } 35 | 36 | MouseEventDTO::MouseEventDTO(int x, int y, bool isAbsoluteMode, int mouseButton) 37 | : absX(x), absY(y), _isAbsoluteMode(isAbsoluteMode) { 38 | MouseEventDTO(x, y, isAbsoluteMode, mouseButton, 0); 39 | if (!isAbsoluteMode) { 40 | // Calculate delta values if not in absolute mode 41 | deltaX = x; // Assuming x is deltaX in relative mode 42 | deltaY = y; // Assuming y is deltaY in relative mode 43 | } 44 | } 45 | 46 | MouseEventDTO::MouseEventDTO(int x, int y, bool isAbsoluteMode) 47 | : absX(x), absY(y), _isAbsoluteMode(isAbsoluteMode) { 48 | MouseEventDTO(x, y, isAbsoluteMode, 0, 0); 49 | if (!isAbsoluteMode) { 50 | // Calculate delta values if not in absolute mode 51 | deltaX = x; // Assuming x is deltaX in relative mode 52 | deltaY = y; // Assuming y is deltaY in relative mode 53 | } 54 | } 55 | 56 | int MouseEventDTO::getX() const { 57 | return _isAbsoluteMode ? absX : deltaX; 58 | } 59 | 60 | int MouseEventDTO::getY() const { 61 | return _isAbsoluteMode ? absY : deltaY; 62 | } 63 | 64 | bool MouseEventDTO::isAbsoluteMode() { 65 | return _isAbsoluteMode; 66 | } 67 | -------------------------------------------------------------------------------- /target/mouseeventdto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef MOUSEEVENTDTO_H 24 | #define MOUSEEVENTDTO_H 25 | 26 | class MouseEventDTO { 27 | public: 28 | MouseEventDTO(int x, int y, bool isAbsoluteMode, int mouseButton, int wheelDelta); 29 | MouseEventDTO(int x, int y, bool isAbsoluteMode, int mouseButton); 30 | MouseEventDTO(int x, int y, bool isAbsoluteMode); 31 | 32 | int getX() const; 33 | int getY() const; 34 | bool isAbsoluteMode(); 35 | int getMouseButton() const { return mouseButton; } 36 | void setMouseButton(int button) { mouseButton = button; } 37 | int getWheelDelta() const { return wheelDelta; } 38 | void setWheelDelta(int delta) { wheelDelta = delta; } 39 | 40 | private: 41 | int absX; 42 | int absY; 43 | int deltaX; 44 | int deltaY; 45 | bool _isAbsoluteMode; 46 | 47 | int mouseButton; 48 | int wheelDelta; 49 | }; 50 | 51 | #endif // MOUSEEVENTDTO_H 52 | -------------------------------------------------------------------------------- /ui/TaskManager.cpp: -------------------------------------------------------------------------------- 1 | #include "TaskManager.h" 2 | 3 | TaskManager* TaskManager::instance() 4 | { 5 | static TaskManager instance; 6 | return &instance; 7 | } 8 | 9 | TaskManager::TaskManager() : m_worker(new Worker()), m_workerThread() 10 | { 11 | m_worker->moveToThread(&m_workerThread); 12 | connect(&m_workerThread, &QThread::started, m_worker, &Worker::onProcessTasks); 13 | m_workerThread.start(); 14 | } 15 | 16 | TaskManager::~TaskManager() 17 | { 18 | { 19 | QMutexLocker locker(&m_worker->m_mutex); 20 | m_worker->m_exit = true; 21 | } 22 | m_worker->m_condition.wakeOne(); 23 | m_workerThread.quit(); 24 | m_workerThread.wait(); 25 | delete m_worker; 26 | } 27 | 28 | void TaskManager::addTask(std::function task) 29 | { 30 | { 31 | QMutexLocker locker(&m_worker->m_mutex); 32 | m_worker->m_taskQueue.enqueue(task); 33 | } 34 | m_worker->m_condition.wakeOne(); 35 | } 36 | 37 | TaskManager::Worker::Worker() : m_exit(false) 38 | { 39 | } 40 | 41 | TaskManager::Worker::~Worker() 42 | { 43 | } 44 | 45 | void TaskManager::Worker::onProcessTasks() 46 | { 47 | while (!m_exit) { 48 | std::function task; 49 | { 50 | QMutexLocker locker(&m_mutex); 51 | if (m_taskQueue.isEmpty()) { 52 | m_condition.wait(&m_mutex); 53 | } 54 | if (!m_taskQueue.isEmpty()) { 55 | task = m_taskQueue.dequeue(); 56 | } 57 | } 58 | if (task) { 59 | task(); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /ui/TaskManager.h: -------------------------------------------------------------------------------- 1 | #ifndef TASKMANAGER_H 2 | #define TASKMANAGER_H 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class TaskManager : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | static TaskManager* instance(); 18 | void addTask(std::function task); 19 | 20 | private: 21 | TaskManager(); 22 | ~TaskManager(); 23 | 24 | class Worker; 25 | Worker *m_worker; 26 | QThread m_workerThread; 27 | }; 28 | 29 | class TaskManager::Worker : public QObject 30 | { 31 | Q_OBJECT 32 | friend class TaskManager; 33 | 34 | public: 35 | Worker(); 36 | ~Worker(); 37 | 38 | private slots: 39 | void onProcessTasks(); 40 | 41 | private: 42 | QQueue> m_taskQueue; 43 | QMutex m_mutex; 44 | QWaitCondition m_condition; 45 | bool m_exit = false; 46 | }; 47 | 48 | #endif // TASKMANAGER_H -------------------------------------------------------------------------------- /ui/advance/envdialog.h: -------------------------------------------------------------------------------- 1 | #ifndef ENVIRONMENTSETUPDIALOG_H 2 | #define ENVIRONMENTSETUPDIALOG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "video/videohid.h" 8 | 9 | namespace Ui { 10 | class EnvironmentSetupDialog; 11 | } 12 | 13 | class EnvironmentSetupDialog : public QDialog 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit EnvironmentSetupDialog(QWidget *parent = nullptr); 19 | ~EnvironmentSetupDialog(); 20 | 21 | // Static method to check if the CH340 driver is installed 22 | static bool checkEnvironmentSetup(); 23 | 24 | static bool autoEnvironmentCheck(); 25 | 26 | protected: 27 | void closeEvent(QCloseEvent *event) override; 28 | 29 | private slots: 30 | void accept() override; 31 | void reject() override; 32 | void extractDriverFiles(); 33 | void copyCommands(); 34 | void openHelpLink(); 35 | #ifdef _WIN32 36 | void installDriverForWindows(); 37 | #endif 38 | 39 | private: 40 | Ui::EnvironmentSetupDialog *ui; 41 | static bool checkDriverInstalled(); 42 | static const QString helpUrl; 43 | 44 | static bool isDriverInstalled; 45 | static const QString tickHtml; 46 | static const QString crossHtml; 47 | static QString lastestFirewareDescription; 48 | static bool isDevicePlugged; 49 | static FirewareResult lastestFirmware; 50 | // bool isDevicePlugged; 51 | 52 | static bool detectDevice(uint16_t vendorID, uint16_t productID); 53 | static bool checkDevicePermission(uint16_t vendorID, uint16_t productID); 54 | 55 | #ifdef __linux__ 56 | static bool checkHidPermission(); 57 | static bool checkBrlttyRunning(); 58 | 59 | static const QString driverCommands; 60 | static const QString groupCommands; 61 | static const QString udevCommands; 62 | static const QString brlttyCommands; 63 | 64 | static bool isInRightUserGroup; 65 | static bool isHidPermission; 66 | static bool isSerialPermission; 67 | static bool isBrlttyRunning; 68 | 69 | QString buildCommands(); 70 | #endif 71 | }; 72 | 73 | #endif // ENVIRONMENTSETUPDIALOG_H -------------------------------------------------------------------------------- /ui/advance/envdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | EnvironmentSetupDialog 4 | 5 | 6 | Environment Helper 7 | 8 | 9 | 10 | 11 | 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | ‣ Extract the driver to a folder: 20 | 21 | 22 | 23 | 24 | 25 | 26 | Select Folder 27 | 28 | 29 | 30 | 31 | 32 | 33 | ‣ Open a terminal and run the following commands: 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | 44 | 45 | false 46 | 47 | 48 | background-color:black; color:white; 49 | 50 | 51 | 52 | 53 | 54 | 55 | 20 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | OK 70 | 71 | 72 | 73 | 74 | 75 | 76 | Quit 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | Auto environment check on startup 86 | 87 | 88 | 89 | 90 | 91 | 92 | <a href="#">Environment Help Documentation</a> 93 | 94 | 95 | Qt::AlignCenter 96 | 97 | 98 | false 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /ui/advance/firmwareupdatedialog.h: -------------------------------------------------------------------------------- 1 | #ifndef FIRMWAREUPDATEDIALOG_H 2 | #define FIRMWAREUPDATEDIALOG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "video/videohid.h" 12 | 13 | class FirmwareUpdateDialog : public QDialog 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit FirmwareUpdateDialog(QWidget *parent = nullptr); 19 | ~FirmwareUpdateDialog() override; 20 | 21 | bool startUpdate(); 22 | 23 | private slots: 24 | void updateProgress(int value); 25 | void updateComplete(bool success); 26 | void onCloseButtonClicked(); 27 | void onProgressTimerTimeout(); 28 | 29 | signals: 30 | void updateFinished(bool success); 31 | 32 | private: 33 | QLabel *statusLabel; 34 | QProgressBar *progressBar; 35 | QPushButton *closeButton; 36 | bool updateResult; 37 | QTimer *progressTimer; 38 | }; 39 | 40 | 41 | class FirmwareUpdateConfirmDialog : public QDialog 42 | { 43 | Q_OBJECT 44 | 45 | public: 46 | explicit FirmwareUpdateConfirmDialog(QWidget *parent = nullptr); 47 | ~FirmwareUpdateConfirmDialog() override; 48 | 49 | // Show the dialog with version information and return user's choice 50 | bool showConfirmDialog(const std::string& currentVersion, const std::string& latestVersion); 51 | 52 | private: 53 | QLabel *messageLabel; 54 | QPushButton *okButton; 55 | QPushButton *cancelButton; 56 | }; 57 | 58 | #endif // FIRMWAREUPDATEDIALOG_H 59 | -------------------------------------------------------------------------------- /ui/advance/scripttool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef SCRIPTTOOL_H 24 | #define SCRIPTTOOL_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "scripts/Lexer.h" 37 | #include "scripts/Parser.h" 38 | #include "scripts/semanticAnalyzer.h" 39 | #include "target/MouseManager.h" 40 | #include "scripts/scriptEditor.h" 41 | 42 | class ScriptTool : public QDialog 43 | { 44 | Q_OBJECT 45 | 46 | public: 47 | explicit ScriptTool(QWidget *parent = nullptr); 48 | ~ScriptTool(); 49 | 50 | signals: 51 | void syntaxTreeReady(std::shared_ptr syntaxTree); 52 | 53 | public slots: 54 | void handleCommandIncrement(); 55 | void resetCommmandLine(bool status); 56 | 57 | private slots: 58 | void selectFile(); 59 | void runScript(); 60 | void saveScript(); 61 | 62 | private: 63 | QLineEdit *filePathEdit; 64 | QPushButton *selectButton; 65 | QPushButton *runButton; 66 | QPushButton *saveButton; 67 | QPushButton *cancelButton; 68 | ScriptEditor *scriptEdit; 69 | QFile currentFile; 70 | Lexer lexer; 71 | std::vector tokens; 72 | QString fileContents; 73 | int commandLine; 74 | int lastHighlightedLine = -1; 75 | void processAST(ASTNode *node); 76 | void highlightTokens(const std::vector& tokens); 77 | }; 78 | 79 | #endif // SCRIPTTOOL_H 80 | 81 | -------------------------------------------------------------------------------- /ui/advance/serialportdebugdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | #ifndef SERIALPORTDEBUGDIALOG_H 25 | #define SERIALPORTDEBUGDIALOG_H 26 | 27 | #include 28 | #include 29 | 30 | class SerialPortDebugDialog : public QDialog { 31 | Q_OBJECT 32 | public: 33 | explicit SerialPortDebugDialog(QWidget *parent = nullptr); 34 | 35 | private slots: 36 | void handleSerialData(const QByteArray &data, bool isReceived); 37 | void getRecvDataAndInsertText(const QByteArray &data) { handleSerialData(data, true); } 38 | void getSentDataAndInsertText(const QByteArray &data) { handleSerialData(data, false); } 39 | 40 | private: 41 | QTextEdit *textEdit; 42 | QWidget *debugButtonWidget; 43 | QWidget *filterCheckboxWidget; 44 | 45 | struct FilterSettings { 46 | const char* name; 47 | const char* label; 48 | unsigned char recvCode; 49 | unsigned char sendCode; 50 | }; 51 | static const FilterSettings FILTERS[]; 52 | 53 | void createDebugButtonWidget(); 54 | void createFilterCheckBox(); 55 | void createLayout(); 56 | void saveSettings(); 57 | void loadSettings(); 58 | QString formatHexData(const QString &hexString); 59 | bool shouldShowMessage(unsigned char code) const; 60 | QString getCommandType(unsigned char code) const; 61 | }; 62 | 63 | #endif // SERIALPORTDEBUGDIALOG_H 64 | -------------------------------------------------------------------------------- /ui/cameraadjust.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef CAMERAAJUST_H 24 | #define CAMERAAJUST_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "host/usbcontrol.h" 33 | 34 | class CameraAdjust : public QWidget 35 | { 36 | Q_OBJECT 37 | 38 | public: 39 | explicit CameraAdjust(QWidget *parent = nullptr); 40 | ~CameraAdjust(); 41 | 42 | void updatePosition(); 43 | void initializeControls(); 44 | 45 | public slots: 46 | void toggleVisibility(); 47 | void updatePosition(int menuBarHeight, int parentWidth); 48 | void updateColors(); 49 | 50 | private slots: 51 | void onContrastChanged(int value); 52 | 53 | private: 54 | void setupUI(); 55 | QSlider *contrastSlider; 56 | QLabel *contrastLabel; 57 | USBControl *usbControl; 58 | }; 59 | 60 | #endif // CAMERAAJUST_H 61 | -------------------------------------------------------------------------------- /ui/cornerwidget/cornerwidgetmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef CORNERWIDGETMANAGER_H 2 | #define CORNERWIDGETMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "ui/toolbar/toggleswitch.h" 10 | 11 | class CornerWidgetManager : public QObject { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit CornerWidgetManager(QWidget *parent = nullptr); 16 | ~CornerWidgetManager(); 17 | 18 | QWidget* getCornerWidget() const; 19 | void setMenuBar(QMenuBar *menuBar); 20 | void updatePosition(int windowWidth, int menuBarHeight, bool isFullScreen); 21 | void initializeKeyboardLayouts(const QStringList &layouts, const QString &defaultLayout); 22 | QPushButton *screensaverButton; 23 | 24 | signals: 25 | void zoomInClicked(); 26 | void zoomOutClicked(); 27 | void zoomReductionClicked(); 28 | void screenScaleClicked(); 29 | void virtualKeyboardClicked(); 30 | void captureClicked(); 31 | void fullScreenClicked(); 32 | void pasteClicked(); 33 | void screensaverClicked(bool checked); 34 | void toggleSwitchChanged(int state); 35 | void keyboardLayoutChanged(const QString &layout); 36 | 37 | private: 38 | void createWidgets(); 39 | void setupConnections(); 40 | void setButtonIcon(QPushButton *button, const QString &iconPath); 41 | 42 | QWidget *cornerWidget; 43 | QComboBox *keyboardLayoutComboBox; 44 | QPushButton *screenScaleButton; 45 | QPushButton *zoomInButton; 46 | QPushButton *zoomOutButton; 47 | QPushButton *zoomReductionButton; 48 | QPushButton *virtualKeyboardButton; 49 | QPushButton *captureButton; 50 | QPushButton *fullScreenButton; 51 | QPushButton *pasteButton; 52 | 53 | ToggleSwitch *toggleSwitch; 54 | QHBoxLayout *horizontalLayout; 55 | QMenuBar *menuBar; 56 | int layoutThreshold; 57 | }; 58 | 59 | #endif // CORNERWIDGETMANAGER_H -------------------------------------------------------------------------------- /ui/globalsetting.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | #ifndef GLOBALSETTING_H 25 | #define GLOBALSETTING_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | class GlobalSetting : public QObject 33 | { 34 | Q_OBJECT 35 | public: 36 | explicit GlobalSetting(QObject *parent = nullptr); 37 | 38 | static GlobalSetting& instance(); 39 | 40 | void setLogSettings(bool core, bool serial, bool ui, bool host); 41 | 42 | void setFilterSettings(bool Chipinfo, bool keyboardPress, bool mideaKeyboard, bool mouseMoveABS, bool mouseMoveREL, bool HID); 43 | 44 | void getFilterSettings(bool &Chipinfo, bool &keyboardPress, bool &mideaKeyboard, bool &mouseMoveABS, bool &mouseMoveREL, bool &HID); 45 | 46 | void loadLogSettings(); 47 | 48 | void setLogStoreSettings(bool storeLog, QString logFilePath); 49 | 50 | void setVideoSettings(int width, int height, int fps); 51 | 52 | void loadVideoSettings(); 53 | 54 | void setCameraDeviceSetting(QString deviceDescription); 55 | 56 | void setVID(QString vid); 57 | 58 | void setPID(QString pid); 59 | 60 | void setUSBEnabelFlag(QString enableflag); 61 | 62 | QByteArray convertStringToByteArray(QString str); 63 | 64 | void setSerialNumber(QString serialNumber); 65 | 66 | void setCustomStringDescriptor(QString customStringDisctriptor); 67 | 68 | void setCustomPIDDescriptor(QString customPIDDescriptor); 69 | 70 | void setCustomVIDDescriptor(QString customVIDDescriptor); 71 | 72 | void setKeyboardLayout(QString keyboardLayout); 73 | 74 | void getKeyboardLayout(QString &keyboardLayout); 75 | 76 | void setMouseAutoHideEnable(bool enable); 77 | 78 | bool getMouseAutoHideEnable(); 79 | 80 | void setLangeuage(QString language); 81 | 82 | void getLanguage(QString &language); 83 | 84 | void setOperatingMode(int mode); 85 | int getOperatingMode() const; 86 | 87 | void setScreenSaverInhibited(bool inhibit); 88 | bool getScreenSaverInhibited() const; 89 | 90 | void setScreenRatio(double ratio); 91 | double getScreenRatio() const; 92 | private: 93 | QSettings m_settings; 94 | }; 95 | 96 | #endif // GLOBALSETTING_H -------------------------------------------------------------------------------- /ui/help/helppane.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #include "helppane.h" 24 | #include 25 | #include 26 | 27 | HelpPane::HelpPane(QWidget *parent) : QWidget(parent) 28 | { 29 | 30 | } 31 | 32 | void HelpPane::paintEvent(QPaintEvent *event) 33 | { 34 | QPainter painter(this); 35 | QColor color("#040707"); 36 | painter.fillRect(this->rect(), color); 37 | QPixmap pixmap(":/images/content_dark_eng.png"); // Replace with the path to your image in the resource file 38 | 39 | int paddingWidth = this->width() * 0.05; 40 | int paddingHeight = this->height() * 0.05; 41 | 42 | // Adjust the rectangle 43 | QRect paddedRect = this->rect().adjusted(paddingWidth, paddingHeight, -paddingWidth, -paddingHeight); 44 | 45 | painter.drawPixmap(paddedRect, pixmap); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /ui/help/helppane.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef HELPPANE_H 24 | #define HELPPANE_H 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | class HelpPane : public QWidget 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | explicit HelpPane(QWidget *parent = nullptr); 36 | 37 | protected: 38 | void paintEvent(QPaintEvent *event) override; // Add this line 39 | 40 | private: 41 | QVBoxLayout *layout; 42 | QLabel *titleLabel; 43 | QLabel *contentLabel; 44 | }; 45 | 46 | #endif // HELPPANE_H 47 | -------------------------------------------------------------------------------- /ui/help/versioninfomanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef VERSIONINFOMANAGER_H 24 | #define VERSIONINFOMANAGER_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | class VersionInfoManager : public QObject 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | explicit VersionInfoManager(QObject *parent = nullptr); 38 | ~VersionInfoManager(); 39 | 40 | void showVersionInfo(); 41 | void showAbout(); 42 | void checkForUpdates(); 43 | 44 | private slots: 45 | void copyToClipboard(); 46 | void handleUpdateCheckResponse(QNetworkReply *reply); 47 | 48 | private: 49 | const QString EMAIL = "info@techxartisan.com"; 50 | const QString TEAM_NAME = "TechxArtisan"; 51 | const QString ADDRESS = "No. 238, Ju De Road, Haizhu District, Guangzhou City, Guangdong Province, China"; 52 | const QString GITHUB_REPO_API = "https://api.github.com/repos/TechxArtisan/Openterface_QT/releases/latest"; 53 | 54 | QNetworkAccessManager *networkManager; 55 | 56 | QString getVersionInfoString() const; 57 | QString getPermissionsStatus() const; 58 | QString getMicrophonePermissionStatus() const; 59 | QString getVideoPermissionStatus() const; 60 | QString getEnvironmentVariables() const; 61 | QString getEnvironmentVariablesPlainText() const; 62 | void openGitHubReleasePage(const QString &releaseUrl); 63 | }; 64 | 65 | #endif // VERSIONINFOMANAGER_H 66 | -------------------------------------------------------------------------------- /ui/inputhandler.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUTHANDLER_H 2 | #define INPUTHANDLER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "target/mouseeventdto.h" 9 | 10 | class VideoPane; // Forward declaration 11 | 12 | class InputHandler : public QObject 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit InputHandler(VideoPane *videoPane, QObject *parent = nullptr); 18 | 19 | void handleKeyPress(QKeyEvent *event); 20 | void handleKeyRelease(QKeyEvent *event); 21 | void handleMousePress(QMouseEvent *event); 22 | void handleMouseRelease(QMouseEvent *event); 23 | void handleMouseMove(QMouseEvent *event); 24 | MouseEventDTO* calculateMouseEventDto(QMouseEvent *event); 25 | void setDragging(bool m_isDragging); 26 | bool isDragging() const { return m_isDragging; } 27 | int getMouseButton(QMouseEvent *event); 28 | 29 | void handleKeyPressEvent(QKeyEvent *event); 30 | void handleKeyReleaseEvent(QKeyEvent *event); 31 | 32 | protected: 33 | bool eventFilter(QObject *watched, QEvent *event) override; 34 | 35 | private: 36 | VideoPane *m_videoPane; 37 | int lastX = 0; 38 | int lastY = 0; 39 | int lastMouseButton = 0; 40 | bool m_isDragging = false; 41 | bool m_holdingEsc = false; 42 | 43 | MouseEventDTO* calculateRelativePosition(QMouseEvent *event); 44 | MouseEventDTO* calculateAbsolutePosition(QMouseEvent *event); 45 | 46 | QSize getScreenResolution(); 47 | 48 | void handleMouseMoveEvent(QMouseEvent *event); 49 | void handleMousePressEvent(QMouseEvent *event); 50 | void handleMouseReleaseEvent(QMouseEvent *event); 51 | void handleWheelEvent(QWheelEvent *event); 52 | }; 53 | 54 | #endif // INPUTHANDLER_H -------------------------------------------------------------------------------- /ui/languagemanager.cpp: -------------------------------------------------------------------------------- 1 | #include "languagemanager.h" 2 | #include "globalsetting.h" 3 | 4 | #include 5 | #include 6 | 7 | LanguageManager::LanguageManager(QApplication *app, QObject *parent) 8 | : QObject(parent), 9 | m_app(app), 10 | m_translator(new QTranslator(this)) 11 | { 12 | 13 | // deployTranslationFiles(); 14 | } 15 | 16 | LanguageManager::~LanguageManager() { 17 | delete m_translator; 18 | } 19 | 20 | 21 | void LanguageManager::initialize(const QString &defaultLanguage) { 22 | Q_UNUSED(defaultLanguage); 23 | GlobalSetting::instance().getLanguage(m_currentLanguage); 24 | switchLanguage(m_currentLanguage); 25 | } 26 | 27 | void LanguageManager::switchLanguage(const QString &language) { 28 | if (!m_currentLanguage.isEmpty()) { 29 | m_app->removeTranslator(m_translator); 30 | } 31 | 32 | QString filePath = QString(":/config/languages/openterface_%1.qm").arg(language); 33 | if (m_translator->load(filePath)) { 34 | m_app->installTranslator(m_translator); 35 | m_currentLanguage = language; 36 | GlobalSetting::instance().setLangeuage(m_currentLanguage); 37 | emit languageChanged(); 38 | } else { 39 | qWarning() << "Failed to load translation file:" << filePath; 40 | } 41 | } 42 | 43 | QStringList LanguageManager::availableLanguages() const { 44 | QDir dir(":/config/languages"); 45 | QStringList filters; 46 | filters << "openterface_*.qm"; 47 | QStringList files = dir.entryList(filters, QDir::Files); 48 | 49 | QStringList languages; 50 | for (const QString &file : files) { 51 | QString lang = file.mid(strlen("openterface_"), file.indexOf('.') - strlen("openterface_")); 52 | languages << lang; 53 | } 54 | return languages; 55 | } 56 | -------------------------------------------------------------------------------- /ui/languagemanager.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_LANGUAGE_MANAGER_H 2 | #define UI_LANGUAGE_MANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class LanguageManager : public QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit LanguageManager(QApplication *app,QObject *parent = nullptr); 14 | ~LanguageManager(); 15 | 16 | void initialize(const QString &defaultLanguage); 17 | void switchLanguage(const QString &language); 18 | 19 | inline QString currentLanguage() const { return m_currentLanguage; }; 20 | 21 | QStringList availableLanguages() const; 22 | 23 | signals: 24 | void languageChanged(); 25 | 26 | 27 | private: 28 | 29 | QApplication *m_app; 30 | QTranslator *m_translator; 31 | QString m_currentLanguage; 32 | QString m_translationPath; 33 | }; 34 | 35 | #endif // UI_LANGUAGE_MANAGER_H -------------------------------------------------------------------------------- /ui/loghandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | #ifndef LOGHANDLER_H 25 | #define LOGHANDLER_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | class LogHandler : public QObject 42 | { 43 | Q_OBJECT 44 | 45 | public: 46 | explicit LogHandler(QObject *parent = nullptr); 47 | 48 | static LogHandler& instance(); 49 | 50 | void enableLogStore(); 51 | 52 | static void fileMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); 53 | static void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); 54 | }; 55 | 56 | 57 | #endif // LOGHANDLER_H 58 | -------------------------------------------------------------------------------- /ui/mainwindow.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | ../images/shutter.svg 4 | ../images/icon_32.png 5 | ../images/icon_32.ico 6 | ../images/icon_64.png 7 | ../images/icon_64.ico 8 | ../images/icon_128.png 9 | ../images/icon_128.ico 10 | ../images/content_dark_eng.png 11 | ../images/paste.svg 12 | ../images/screensaver.svg 13 | ../images/mouse-left-button.svg 14 | ../images/mouse-right-button.svg 15 | ../images/mouse-default.svg 16 | ../images/mouse-middle-button.svg 17 | ../images/keyboard.svg 18 | ../images/keyboard-pressed.svg 19 | ../images/keyboard-down.svg 20 | ../images/keyboard-up.svg 21 | ../images/zoom_in.svg 22 | ../images/zoom_out.svg 23 | ../images/contrast.svg 24 | ../images/capture.svg 25 | ../images/full_screen.svg 26 | ../images/zoom_fit.svg 27 | ../images/fullscreen.svg 28 | ../images/screen_scale.svg 29 | 30 | 31 | -------------------------------------------------------------------------------- /ui/preferences/audiopage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #include "audiopage.h" 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | AudioPage::AudioPage(QWidget *parent) : QWidget(parent) 32 | { 33 | setupUI(); 34 | } 35 | 36 | void AudioPage::setupUI() 37 | { 38 | QLabel *audioLabel = new QLabel( 39 | QString("%1").arg(tr("General audio setting"))); 40 | audioLabel->setStyleSheet(bigLabelFontSize); 41 | 42 | QLabel *audioCodecLabel = new QLabel(tr("Audio Codec: ")); 43 | audioCodecLabel->setStyleSheet(smallLabelFontSize); 44 | QComboBox *audioCodecBox = new QComboBox(); 45 | audioCodecBox->setObjectName("audioCodecBox"); 46 | 47 | QLabel *audioSampleRateLabel = new QLabel(tr("Sample Rate: ")); 48 | audioSampleRateLabel->setStyleSheet(smallLabelFontSize); 49 | QSpinBox *audioSampleRateBox = new QSpinBox(); 50 | audioSampleRateBox->setObjectName("audioSampleRateBox"); 51 | audioSampleRateBox->setEnabled(false); 52 | 53 | QLabel *qualityLabel = new QLabel(tr("Quality: ")); 54 | qualityLabel->setStyleSheet(smallLabelFontSize); 55 | 56 | QSlider *qualitySlider = new QSlider(); 57 | qualitySlider->setObjectName("qualitySlider"); 58 | qualitySlider->setOrientation(Qt::Horizontal); 59 | 60 | QLabel *fileFormatLabel = new QLabel(tr("File Format: ")); 61 | fileFormatLabel->setStyleSheet(smallLabelFontSize); 62 | 63 | QComboBox *containerFormatBox = new QComboBox(); 64 | containerFormatBox->setObjectName("containerFormatBox"); 65 | 66 | QVBoxLayout *audioLayout = new QVBoxLayout(this); 67 | audioLayout->addWidget(audioLabel); 68 | audioLayout->addWidget(audioCodecLabel); 69 | audioLayout->addWidget(audioCodecBox); 70 | audioLayout->addWidget(audioSampleRateLabel); 71 | audioLayout->addWidget(audioSampleRateBox); 72 | audioLayout->addWidget(qualityLabel); 73 | audioLayout->addWidget(qualitySlider); 74 | audioLayout->addWidget(fileFormatLabel); 75 | audioLayout->addWidget(containerFormatBox); 76 | audioLayout->addStretch(); 77 | } 78 | -------------------------------------------------------------------------------- /ui/preferences/audiopage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef AUDIOPAGE_H 24 | #define AUDIOPAGE_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "fontstyle.h" 34 | 35 | class AudioPage : public QWidget 36 | { 37 | Q_OBJECT 38 | public: 39 | explicit AudioPage(QWidget *parent = nullptr); 40 | void setupUI(); 41 | private: 42 | QLabel *audioLabel; 43 | QLabel *audioCodecLabel; 44 | QComboBox *audioCodecBox; 45 | QLabel *audioSampleRateLabel; 46 | QSpinBox *audioSampleRateBox; 47 | QLabel *qualityLabel; 48 | QSlider *qualitySlider; 49 | QLabel *fileFormatLabel; 50 | QComboBox *containerFormatBox; 51 | }; 52 | 53 | #endif // AUDIOPAGE_H -------------------------------------------------------------------------------- /ui/preferences/cameraadjust.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef CAMERAAJUST_H 24 | #define CAMERAAJUST_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "host/usbcontrol.h" 33 | 34 | class CameraAdjust : public QWidget 35 | { 36 | Q_OBJECT 37 | 38 | public: 39 | explicit CameraAdjust(QWidget *parent = nullptr); 40 | ~CameraAdjust(); 41 | 42 | void updatePosition(); 43 | void initializeControls(); 44 | 45 | public slots: 46 | void toggleVisibility(); 47 | void updatePosition(int menuBarHeight, int parentWidth); 48 | void updateColors(); 49 | 50 | private slots: 51 | void onContrastChanged(int value); 52 | 53 | private: 54 | void setupUI(); 55 | QSlider *contrastSlider; 56 | QLabel *contrastLabel; 57 | USBControl *usbControl; 58 | }; 59 | 60 | #endif // CAMERAAJUST_H 61 | -------------------------------------------------------------------------------- /ui/preferences/fontstyle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef FONTSTYLE_H 24 | #define FONTSTYLE_H 25 | 26 | #include 27 | 28 | const QString bigLabelFontSize = "QLabel { font-size: 14px; }"; 29 | const QString smallLabelFontSize = "QLabel { font-size: 12px; }"; 30 | const QString commentsFontSize = "QLabel { font-size: 10px; }"; 31 | 32 | #endif // FONTSTYLE_H 33 | 34 | 35 | -------------------------------------------------------------------------------- /ui/preferences/fpsspinbox.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | #include "fpsspinbox.h" 25 | 26 | FpsSpinBox::FpsSpinBox(QWidget *parent) 27 | : QSpinBox(parent) 28 | { 29 | } 30 | 31 | void FpsSpinBox::setValidValues(const std::set &values) 32 | { 33 | validValues = values; 34 | if (!validValues.empty()) { 35 | setRange(*validValues.begin(), *validValues.rbegin()); 36 | } 37 | } 38 | 39 | void FpsSpinBox::stepBy(int steps) 40 | { 41 | if (validValues.empty()) { 42 | QSpinBox::stepBy(steps); 43 | return; 44 | } 45 | 46 | int currentValue = value(); 47 | auto it = validValues.find(currentValue); 48 | 49 | if (steps > 0) { // Incrementing 50 | if (it != validValues.end()) ++it; 51 | if (it != validValues.end()) setValue(*it); 52 | } else if (steps < 0) { // Decrementing 53 | if (it == validValues.begin() || it == validValues.end()) { 54 | // If it's the first element or not found, do nothing special 55 | } else { 56 | --it; 57 | setValue(*it); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ui/preferences/fpsspinbox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | 24 | 25 | #ifndef FPSSPINBOX_H 26 | #define FPSSPINBOX_H 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | class FpsSpinBox : public QSpinBox 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | explicit FpsSpinBox(QWidget *parent = nullptr); 38 | void setValidValues(const std::set &values); 39 | 40 | protected: 41 | void stepBy(int steps) override; 42 | 43 | private: 44 | std::set validValues; 45 | 46 | }; 47 | #endif // FPSSPINBOX_H 48 | -------------------------------------------------------------------------------- /ui/preferences/logpage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef LOGPAGE_H 24 | #define LOGPAGE_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "fontstyle.h" 35 | 36 | class LogPage : public QWidget 37 | { 38 | Q_OBJECT 39 | 40 | public: 41 | explicit LogPage(QWidget *parent = nullptr); 42 | void setupUI(); 43 | void browseLogPath(); 44 | void initLogSettings(); 45 | void applyLogsettings(); 46 | 47 | signals: 48 | void ScreenSaverInhibitedChanged(bool inhibited); 49 | 50 | private: 51 | 52 | QCheckBox *coreCheckBox; 53 | QCheckBox *serialCheckBox; 54 | QCheckBox *uiCheckBox; 55 | QCheckBox *hostCheckBox; 56 | QCheckBox *storeLogCheckBox; 57 | QLineEdit *logFilePathLineEdit; 58 | QPushButton *browseButton; 59 | QCheckBox *screenSaverCheckBox; 60 | 61 | QHBoxLayout *logCheckboxLayout; 62 | QHBoxLayout *logFilePathLayout; 63 | QLabel *logLabel; 64 | QLabel *logDescription; 65 | QVBoxLayout *logLayout; 66 | }; 67 | 68 | #endif // LOGPAGE_H 69 | -------------------------------------------------------------------------------- /ui/preferences/settingdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef SETTINGDIALOG_H 24 | #define SETTINGDIALOG_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include "host/cameramanager.h" 41 | #include "logpage.h" 42 | #include "targetcontrolpage.h" 43 | #include "videopage.h" 44 | #include "audiopage.h" 45 | QT_BEGIN_NAMESPACE 46 | class QCameraFormat; 47 | class QComboBox; 48 | class QCamera; 49 | namespace Ui { 50 | class SettingDialog; 51 | } 52 | QT_END_NAMESPACE 53 | 54 | class SettingDialog : public QDialog 55 | { 56 | Q_OBJECT 57 | 58 | public: 59 | // Change the constructor to accept CameraManager instead of QCamera 60 | explicit SettingDialog(CameraManager *cameraManager, QWidget *parent = nullptr); 61 | ~SettingDialog(); 62 | TargetControlPage* getTargetControlPage(); 63 | VideoPage* getVideoPage(); 64 | 65 | LogPage* getLogPage(); 66 | 67 | // signals: 68 | // // void serialSettingsApplied(); 69 | 70 | private: 71 | 72 | Ui::SettingDialog *ui; 73 | CameraManager *m_cameraManager; 74 | QTreeWidget *settingTree; 75 | QStackedWidget *stackedWidget; 76 | LogPage *logPage; 77 | QWidget *audioPage; 78 | VideoPage *videoPage; 79 | TargetControlPage *targetControlPage; 80 | 81 | QWidget *buttonWidget; 82 | 83 | void createSettingTree(); 84 | void createLayout(); 85 | void createPages(); 86 | 87 | void changePage(QTreeWidgetItem *current, QTreeWidgetItem *previous); 88 | void createButtons(); 89 | void applyAccrodingPage(); 90 | void handleOkButton(); 91 | }; 92 | 93 | #endif // SETTINGDIALOG_H 94 | -------------------------------------------------------------------------------- /ui/preferences/settingdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SettingDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 440 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ui/preferences/targetcontrolpage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef TARGETCONTROL_H 24 | #define TARGETCONTROL_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "host/cameramanager.h" 40 | #include "fontstyle.h" 41 | 42 | class TargetControlPage : public QWidget 43 | { 44 | Q_OBJECT 45 | public: 46 | explicit TargetControlPage(QWidget *parent = nullptr); 47 | void setupUI(); 48 | void applyHardwareSetting(); 49 | void initHardwareSetting(); 50 | 51 | private: 52 | QLabel *hardwareLabel; 53 | QLabel *VIDPIDLabel; 54 | QLabel *VID; 55 | QLabel *PID; 56 | QCheckBox *VIDCheckBox; 57 | QCheckBox *PIDCheckBox; 58 | QCheckBox *USBSerialNumberCheckBox; 59 | QCheckBox *USBCustomStringDescriptorCheckBox; 60 | QLineEdit *VIDLineEdit; 61 | QLineEdit *PIDLineEdit; 62 | QLineEdit *VIDDescriptorLineEdit; 63 | QLineEdit *PIDDescriptorLineEdit; 64 | QLineEdit *serialNumberLineEdit; 65 | 66 | void addCheckBoxLineEditPair(QCheckBox *checkBox, QLineEdit *lineEdit); 67 | void onCheckBoxStateChanged(int state); 68 | 69 | std::array extractBits(QString hexString); 70 | QByteArray convertCheckBoxValueToBytes(); 71 | QMap USBCheckBoxEditMap; // map of checkboxes to line edit about VID PID etc. 72 | 73 | // Operating mode widgets 74 | QButtonGroup *operatingModeGroup; 75 | QRadioButton *fullModeRadio; 76 | QRadioButton *keyboardOnlyRadio; 77 | QRadioButton *keyboardMouseRadio; 78 | QRadioButton *customHIDRadio; 79 | 80 | const QString bigLabelFontSize = "font-size: 16px;"; 81 | 82 | int originalOperatingMode; 83 | }; 84 | 85 | #endif // TARGETCONTROL_H 86 | 87 | -------------------------------------------------------------------------------- /ui/preferences/videopage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef VIDEOPAGE_H 24 | #define VIDEOPAGE_H 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "fontstyle.h" 34 | #include "host/cameramanager.h" 35 | #include 36 | #include "ui/globalsetting.h" 37 | #include "global.h" 38 | 39 | QT_BEGIN_NAMESPACE 40 | class QCameraFormat; 41 | QT_END_NAMESPACE 42 | 43 | 44 | struct QSizeComparator { 45 | bool operator()(const QSize& lhs, const QSize& rhs) const { 46 | if (lhs.width() == rhs.width()) { 47 | return lhs.height() > rhs.height(); // Compare heights in descending order 48 | } 49 | return lhs.width() > rhs.width(); // Compare widths in descending order 50 | } 51 | }; 52 | 53 | class VideoPage : public QWidget 54 | { 55 | Q_OBJECT 56 | public: 57 | explicit VideoPage(CameraManager *cameraManager, QWidget *parent = nullptr); 58 | void setupUI(); 59 | void initVideoSettings(); 60 | void applyVideoSettings(); 61 | 62 | signals: 63 | void videoSettingsChanged(); 64 | void inputResolutionChanged(const QSize &resolution); 65 | void cameraSettingsApplied(); 66 | void cameraDeviceChanged(); 67 | 68 | private slots: 69 | void toggleCustomResolutionInputs(bool checked); 70 | 71 | private: 72 | CameraManager *m_cameraManager; 73 | QSize m_currentResolution; 74 | bool m_updatingFormats = false; 75 | 76 | QLabel *uvcCamLabel; 77 | QComboBox *uvcCamBox; 78 | QLabel *videoLabel; 79 | QLabel *resolutionsLabel; 80 | QComboBox *videoFormatBox; 81 | QLabel *framerateLabel; 82 | QComboBox *fpsComboBox; 83 | QLabel *formatLabel; 84 | QComboBox *pixelFormatBox; 85 | void populateResolutionBox(const QList &videoFormats); 86 | void setFpsRange(const std::set &fpsValues); 87 | void handleResolutionSettings(); 88 | QVariant boxValue(const QComboBox *) const; 89 | void updatePixelFormats(); 90 | void findUvcCameraDevices(); 91 | 92 | }; 93 | 94 | #endif // VIDEOPAGE_H 95 | 96 | -------------------------------------------------------------------------------- /ui/screensavermanager.cpp: -------------------------------------------------------------------------------- 1 | // ScreenSaverManager.cpp 2 | #include "ui/screensavermanager.h" 3 | #include 4 | 5 | ScreenSaverManager::ScreenSaverManager(QObject *parent) 6 | : QObject(parent) { 7 | loadSettings(); 8 | } 9 | 10 | ScreenSaverManager::~ScreenSaverManager() { 11 | 12 | if (m_isInhibited) { 13 | uninhibitScreenSaver(); 14 | } 15 | } 16 | 17 | void ScreenSaverManager::loadSettings() { 18 | bool savedState = GlobalSetting::instance().getScreenSaverInhibited(); 19 | m_isInhibited = savedState; // load the state from QSettings 20 | if (m_isInhibited) { 21 | inhibitScreenSaver(); 22 | } else { 23 | uninhibitScreenSaver(); 24 | } 25 | } 26 | 27 | void ScreenSaverManager::setScreenSaverInhibited(bool inhibit) { 28 | if (m_isInhibited == inhibit) { 29 | return; 30 | } 31 | 32 | if (inhibit) { 33 | inhibitScreenSaver(); 34 | } else { 35 | uninhibitScreenSaver(); 36 | } 37 | 38 | m_isInhibited = inhibit; 39 | GlobalSetting::instance().setScreenSaverInhibited(m_isInhibited); // save the state to QSettings 40 | } 41 | 42 | void ScreenSaverManager::inhibitScreenSaver() { 43 | #ifdef Q_OS_WIN 44 | // Windows: inhibit screen saver using SetThreadExecutionState 45 | SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED); 46 | qDebug() << "Screen saver inhibited on Windows"; 47 | #endif 48 | #ifdef Q_OS_LINUX 49 | // Linux: use DBus to inhibit screen saver 50 | QDBusInterface screenSaver("org.freedesktop.ScreenSaver", 51 | "/org/freedesktop/ScreenSaver", 52 | "org.freedesktop.ScreenSaver"); 53 | if (screenSaver.isValid()) { 54 | QDBusReply reply = screenSaver.call("Inhibit", "OpenterfaceQt", "Running KVM application"); 55 | if (reply.isValid()) { 56 | m_cookie = reply.value(); 57 | qDebug() << "Screen saver inhibited on Linux with cookie:" << m_cookie; 58 | } else { 59 | qWarning() << "Failed to inhibit screen saver on Linux:" << reply.error().message(); 60 | } 61 | } 62 | #endif 63 | } 64 | 65 | void ScreenSaverManager::uninhibitScreenSaver() { 66 | #ifdef Q_OS_WIN 67 | // Windows: recover screen saver using SetThreadExecutionState 68 | SetThreadExecutionState(ES_CONTINUOUS); 69 | qDebug() << "Screen saver uninhibited on Windows"; 70 | #endif 71 | #ifdef Q_OS_LINUX 72 | // Linux: DBus recovery screen saver 73 | QDBusInterface screenSaver("org.freedesktop.ScreenSaver", 74 | "/org/freedesktop/ScreenSaver", 75 | "org.freedesktop.ScreenSaver"); 76 | if (screenSaver.isValid() && m_cookie != 0) { 77 | screenSaver.call("UnInhibit", m_cookie); 78 | qDebug() << "Screen saver uninhibited on Linux with cookie:" << m_cookie; 79 | m_cookie = 0; 80 | } 81 | #endif 82 | } -------------------------------------------------------------------------------- /ui/screensavermanager.h: -------------------------------------------------------------------------------- 1 | // ScreenSaverManager.h 2 | #ifndef SCREENSAVERMANAGER_H 3 | #define SCREENSAVERMANAGER_H 4 | 5 | #include 6 | #include "ui/globalsetting.h" 7 | #ifdef Q_OS_WIN 8 | #include 9 | #endif 10 | #ifdef Q_OS_LINUX 11 | #include 12 | #include 13 | #endif 14 | 15 | class ScreenSaverManager : public QObject { 16 | Q_OBJECT 17 | public: 18 | explicit ScreenSaverManager(QObject *parent = nullptr); 19 | ~ScreenSaverManager(); 20 | 21 | bool isScreenSaverInhibited() const { return m_isInhibited; } 22 | 23 | void loadSettings(); 24 | 25 | public slots: 26 | void setScreenSaverInhibited(bool inhibit); 27 | 28 | private: 29 | void inhibitScreenSaver(); 30 | void uninhibitScreenSaver(); 31 | 32 | bool m_isInhibited = false; 33 | QSettings m_settings; 34 | #ifdef Q_OS_LINUX 35 | uint m_cookie = 0; 36 | #endif 37 | }; 38 | 39 | #endif // SCREENSAVERMANAGER_H -------------------------------------------------------------------------------- /ui/screenscale.cpp: -------------------------------------------------------------------------------- 1 | #include "screenscale.h" 2 | #include "ui/globalsetting.h" 3 | #include 4 | 5 | ScreenScale::ScreenScale(QWidget *parent) : QDialog(parent) 6 | { 7 | // Set dialog title 8 | setWindowTitle(tr("Screen Aspect Ratio")); 9 | 10 | // Initialize widgets 11 | ratioComboBox = new QComboBox(this); 12 | okButton = new QPushButton("OK", this); 13 | cancelButton = new QPushButton("Cancel", this); 14 | 15 | // Populate combo box with common screen aspect ratios 16 | ratioComboBox->addItem("16:9"); 17 | ratioComboBox->addItem("4:3"); 18 | ratioComboBox->addItem("16:10"); 19 | ratioComboBox->addItem("5:3"); 20 | ratioComboBox->addItem("5:4"); 21 | ratioComboBox->addItem("21:9"); 22 | // ratioComboBox->addItem("9:16"); 23 | // ratioComboBox->addItem("9:19.5"); 24 | // ratioComboBox->addItem("9:20"); 25 | // ratioComboBox->addItem("9:21"); 26 | 27 | setFixedSize(200, 150); 28 | // Set up layout 29 | layout = new QVBoxLayout(this); 30 | layout->addWidget(ratioComboBox); 31 | layoutBtn = new QHBoxLayout(this); 32 | layoutBtn->addWidget(okButton); 33 | layoutBtn->addWidget(cancelButton); 34 | layout->addLayout(layoutBtn); 35 | 36 | double savedRatio = GlobalSetting::instance().getScreenRatio(); 37 | QString savedRatioStr = converseRatio(savedRatio); 38 | int index = ratioComboBox->findText(savedRatioStr); 39 | if (index != -1) ratioComboBox->setCurrentIndex(index); 40 | 41 | // Connect buttons to slots 42 | connect(okButton, &QPushButton::clicked, this, &ScreenScale::onOkClicked); 43 | connect(cancelButton, &QPushButton::clicked, this, &ScreenScale::onCancelClicked); 44 | 45 | // Set layout to dialog 46 | setLayout(layout); 47 | } 48 | 49 | ScreenScale::~ScreenScale() 50 | { 51 | // Qt handles widget deletion via parent-child hierarchy 52 | } 53 | 54 | QString ScreenScale::getSelectedRatio() const 55 | { 56 | return ratioComboBox->currentText(); 57 | } 58 | 59 | double ScreenScale::converseRatio(QString ratio){ 60 | QStringList parts = ratio.split(":"); 61 | if (parts.size() == 2) { 62 | bool ok1, ok2; 63 | float num1 = parts[0].toFloat(&ok1); 64 | float num2 = parts[1].toFloat(&ok2); 65 | double result = static_cast(num1) / num2; 66 | return result; 67 | } 68 | } 69 | 70 | QString ScreenScale::converseRatio(double ratio) { 71 | if (qFuzzyCompare(ratio, 16.0/9.0)) return "16:9"; 72 | if (qFuzzyCompare(ratio, 4.0/3.0)) return "4:3"; 73 | if (qFuzzyCompare(ratio, 16.0/10.0)) return "16:10"; 74 | if (qFuzzyCompare(ratio, 5.0/3.0)) return "5:3"; 75 | if (qFuzzyCompare(ratio, 5.0/4.0)) return "5:4"; 76 | if (qFuzzyCompare(ratio, 21.0/9.0)) return "21:9"; 77 | if (qFuzzyCompare(ratio, 9.0/16.0)) return "9:16"; 78 | if (qFuzzyCompare(ratio, 9.0/19.5)) return "9:19.5"; 79 | if (qFuzzyCompare(ratio, 9.0/20.0)) return "9:20"; 80 | if (qFuzzyCompare(ratio, 9.0/21.0)) return "9:21"; 81 | return "16:9"; 82 | } 83 | 84 | void ScreenScale::onOkClicked() 85 | { 86 | // Emit signal with selected ratio 87 | QString selectedRatio = getSelectedRatio(); 88 | // GlobalSetting::instance().setScreenRatio(selectedRatio); 89 | qDebug() << "ScreenScale::onOkClicked" << selectedRatio; 90 | double ratio = converseRatio(selectedRatio); 91 | emit screenRatio(ratio); 92 | qDebug() << "ScreenScale::onOkClicked" << ratio; 93 | accept(); // Close dialog with QDialog::Accepted status 94 | } 95 | 96 | void ScreenScale::onCancelClicked() 97 | { 98 | reject(); // Close dialog with QDialog::Rejected status 99 | } -------------------------------------------------------------------------------- /ui/screenscale.h: -------------------------------------------------------------------------------- 1 | #ifndef SCREENSCALE_H 2 | #define SCREENSCALE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class ScreenScale : public QDialog 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit ScreenScale(QWidget *parent = nullptr); 15 | ~ScreenScale(); 16 | 17 | QString getSelectedRatio() const; 18 | 19 | signals: 20 | void screenRatio(double ratio); 21 | 22 | private slots: 23 | void onOkClicked(); 24 | void onCancelClicked(); 25 | 26 | private: 27 | QComboBox *ratioComboBox; 28 | QPushButton *okButton; 29 | QPushButton *cancelButton; 30 | QVBoxLayout *layout; 31 | QHBoxLayout *layoutBtn; 32 | double converseRatio(QString ratio); 33 | QString converseRatio(double ratio); 34 | }; 35 | 36 | #endif // SCREENSCALE_H 37 | -------------------------------------------------------------------------------- /ui/statusbar/statusbarmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef STATUSBARMANAGER_H 2 | #define STATUSBARMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "statuswidget.h" 10 | 11 | class StatusBarManager : public QObject 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit StatusBarManager(QStatusBar *statusBar, QObject *parent = nullptr); 17 | 18 | void initStatusBar(); 19 | void onLastKeyPressed(const QString& key); 20 | void onLastMouseLocation(const QPoint& location, const QString& mouseEvent); 21 | void setConnectedPort(const QString& port, const int& baudrate); 22 | void setStatusUpdate(const QString& status); 23 | void setInputResolution(int width, int height, float fps, float pixelClk); 24 | void setCaptureResolution(int width, int height, int fps); 25 | void setTargetUsbConnected(bool isConnected); 26 | void updateIconColor(); 27 | 28 | private: 29 | QStatusBar *m_statusBar; 30 | StatusWidget *m_statusWidget; 31 | QLabel *mouseLabel; 32 | QLabel *mouseLocationLabel; 33 | QLabel *keyPressedLabel; 34 | QLabel *keyLabel; 35 | QColor iconColor; 36 | 37 | QPixmap recolorSvg(const QString &svgPath, const QColor &color, const QSize &size); 38 | QColor getContrastingColor(const QColor &color); 39 | QString m_currentPort; 40 | void updateKeyboardIcon(const QString& key); 41 | }; 42 | 43 | #endif // STATUSBARMANAGER_H -------------------------------------------------------------------------------- /ui/statusbar/statuswidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef STATUSWIDGET_H 24 | #define STATUSWIDGET_H 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | class StatusWidget : public QWidget { 31 | Q_OBJECT 32 | 33 | public: 34 | explicit StatusWidget(QWidget *parent = nullptr); 35 | 36 | void setInputResolution(const int &width, const int &height, const float &fps, const float &pixelClk); 37 | void setCaptureResolution(const int &width, const int &height, const float &fps); 38 | void setKeyboardIndicators(const QString &indicators); 39 | void setConnectedPort(const QString &port, const int &baudrate); 40 | void setStatusUpdate(const QString &status); 41 | void setTargetUsbConnected(const bool isConnected); 42 | int getCaptureWidth() const; 43 | int getCaptureHeight() const; 44 | 45 | public slots: 46 | void setBaudrate(int baudrate); 47 | 48 | private: 49 | QLabel *statusLabel; 50 | QLabel *keyboardIndicatorsLabel; 51 | QLabel *resolutionLabel; 52 | QLabel *inputResolutionLabel; 53 | QLabel *captureResolutionLabel; 54 | QLabel *connectedPortLabel; 55 | int m_captureWidth; 56 | int m_captureHeight; 57 | }; 58 | 59 | #endif // STATUSWIDGET_H 60 | -------------------------------------------------------------------------------- /ui/statusevents.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef SERIALPORTEVENTS_H 24 | #define SERIALPORTEVENTS_H 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | class StatusEventCallback 31 | { 32 | public: 33 | virtual ~StatusEventCallback() = default; 34 | 35 | virtual void onStatusUpdate(const QString& status) = 0; 36 | virtual void onPortConnected(const QString& port, const int& baudrate) = 0; 37 | virtual void onLastKeyPressed(const QString& key) = 0; 38 | virtual void onLastMouseLocation(const QPoint& location, const QString& mouseEvent) = 0; 39 | // virtual void onResolutionChange(const int& width, const int& height, const float& fps, const float& pixelClk) = 0; 40 | virtual void onSwitchableUsbToggle(const bool isToTarget) = 0; 41 | virtual void onTargetUsbConnected(const bool isConnected) = 0; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /ui/toolbar/toggleswitch.cpp: -------------------------------------------------------------------------------- 1 | #include "toggleswitch.h" 2 | 3 | ToggleSwitch::ToggleSwitch(QWidget *parent, QColor barColor, QColor checkedColor, 4 | QColor handleColor, float hScale, float vScale, int fontSize) 5 | : QCheckBox(parent), 6 | m_barBrush(barColor), 7 | m_barCheckedBrush(checkedColor), 8 | m_handleBrush(handleColor), 9 | m_handleCheckedBrush(checkedColor), 10 | m_handlePosition(0), 11 | m_hScale(hScale), 12 | m_vScale(vScale), 13 | m_fontSize(fontSize) 14 | { 15 | setContentsMargins(7, 0, 7, 0); 16 | connect(this, &QCheckBox::stateChanged, this, &ToggleSwitch::handleStateChange); 17 | } 18 | 19 | QSize ToggleSwitch::sizeHint() const 20 | { 21 | return QSize(58, 45); 22 | } 23 | 24 | bool ToggleSwitch::hitButton(const QPoint &pos) const 25 | { 26 | return contentsRect().contains(pos); 27 | } 28 | 29 | void ToggleSwitch::paintEvent(QPaintEvent *e) 30 | { 31 | Q_UNUSED(e); 32 | 33 | QPainter p(this); 34 | p.setRenderHint(QPainter::Antialiasing); 35 | 36 | QRect contRect = contentsRect(); 37 | qreal width = contRect.width() * m_hScale; 38 | qreal height = contRect.height() * m_vScale; 39 | qreal handleRadius = qRound(0.24 * height); 40 | 41 | p.setPen(Qt::NoPen); 42 | QRectF barRect(0, 0, width - handleRadius, 0.50 * height); 43 | barRect.moveCenter(contRect.center()); 44 | qreal rounding = barRect.height() / 2; 45 | 46 | qreal trailLength = contRect.width() * m_hScale - 2 * handleRadius; 47 | qreal xLeft = contRect.center().x() - (trailLength + handleRadius) / 2; 48 | qreal xPos = xLeft + handleRadius + trailLength * m_handlePosition - 3; 49 | 50 | if (isChecked()) { 51 | p.setBrush(m_barCheckedBrush); 52 | p.drawRoundedRect(barRect, rounding, rounding); 53 | 54 | p.setPen(Qt::black); 55 | p.setFont(QFont("Helvetica", m_fontSize, QFont::Bold)); 56 | p.drawText(QRectF(xLeft, contRect.top(), trailLength, contRect.height()), Qt::AlignCenter, "Target"); 57 | } else { 58 | p.setBrush(m_barBrush); 59 | p.drawRoundedRect(barRect, rounding, rounding); 60 | 61 | p.setPen(Qt::black); 62 | p.setFont(QFont("Helvetica", m_fontSize, QFont::Bold)); 63 | p.drawText(QRectF(xLeft, contRect.top(), trailLength, contRect.height()), Qt::AlignCenter, " Host"); 64 | } 65 | 66 | // Use m_handleBrush for both checked and unchecked states 67 | p.setBrush(m_handleBrush); 68 | p.setPen(Qt::lightGray); 69 | p.drawEllipse(QPointF(xPos, barRect.center().y()), handleRadius, handleRadius); 70 | } 71 | 72 | void ToggleSwitch::handleStateChange(int value) 73 | { 74 | m_handlePosition = value ? 1 : 0; 75 | update(); 76 | } 77 | 78 | void ToggleSwitch::setHandlePosition(float pos) 79 | { 80 | if (m_handlePosition != pos) { 81 | m_handlePosition = pos; 82 | emit handlePositionChanged(pos); 83 | update(); 84 | } 85 | } 86 | 87 | void ToggleSwitch::setHScale(float value) 88 | { 89 | if (m_hScale != value) { 90 | m_hScale = value; 91 | update(); 92 | } 93 | } 94 | 95 | void ToggleSwitch::setVScale(float value) 96 | { 97 | if (m_vScale != value) { 98 | m_vScale = value; 99 | update(); 100 | } 101 | } 102 | 103 | void ToggleSwitch::setFontSize(int value) 104 | { 105 | if (m_fontSize != value) { 106 | m_fontSize = value; 107 | update(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /ui/toolbar/toggleswitch.h: -------------------------------------------------------------------------------- 1 | #ifndef TOGGLESWITCH_H 2 | #define TOGGLESWITCH_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class ToggleSwitch : public QCheckBox 9 | { 10 | Q_OBJECT 11 | Q_PROPERTY(float handlePosition READ handlePosition WRITE setHandlePosition NOTIFY handlePositionChanged) 12 | 13 | public: 14 | explicit ToggleSwitch(QWidget *parent = nullptr, 15 | QColor barColor = QColor(242, 145, 58), // Replace "#F2913A" 16 | QColor checkedColor = QColor(242, 145, 58), // Replace "#F2913A" 17 | QColor handleColor = QColor(252, 241, 230), 18 | float hScale = 1.0f, 19 | float vScale = 1.1f, 20 | int fontSize = 9); 21 | 22 | QSize sizeHint() const override; 23 | bool hitButton(const QPoint &pos) const override; 24 | 25 | float handlePosition() const { return m_handlePosition; } 26 | void setHandlePosition(float pos); 27 | 28 | void setHScale(float value); 29 | void setVScale(float value); 30 | void setFontSize(int value); 31 | 32 | signals: 33 | void handlePositionChanged(float position); 34 | 35 | protected: 36 | void paintEvent(QPaintEvent *e) override; 37 | 38 | private slots: 39 | void handleStateChange(int value); 40 | 41 | private: 42 | QBrush m_barBrush; 43 | QBrush m_barCheckedBrush; 44 | QBrush m_handleBrush; 45 | QBrush m_handleCheckedBrush; 46 | float m_handlePosition; 47 | float m_hScale; 48 | float m_vScale; 49 | int m_fontSize; 50 | }; 51 | 52 | #endif // TOGGLESWITCH_H 53 | -------------------------------------------------------------------------------- /ui/toolbar/toolbarmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef TOOLBARMANAGER_H 2 | #define TOOLBARMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | class ToolbarManager : public QObject 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit ToolbarManager(QWidget *parent = nullptr); 19 | QToolBar* getToolbar() { return toolbar; } 20 | 21 | // Add this line to declare the toggleToolbar function 22 | void toggleToolbar(); 23 | void updateStyles(); 24 | 25 | signals: 26 | void toolbarVisibilityChanged(bool visible); 27 | 28 | private: 29 | struct KeyInfo { 30 | QString text; 31 | QString toolTip; 32 | int keyCode; 33 | }; 34 | 35 | static const QString commonButtonStyle; 36 | 37 | // Define constants for all special keys 38 | static const QList modifierKeys; 39 | static const QList specialKeys; 40 | 41 | // Dynamic Qt property name for key codes 42 | static const char *KEYCODE_PROPERTY; 43 | static const char *MODIFIER_PROPERTY; 44 | 45 | QToolBar *toolbar; 46 | void setupToolbar(); 47 | QPushButton *addKeyButton(const QString& text, const QString& toolTip); 48 | 49 | private slots: 50 | void onKeyButtonClicked(); 51 | void onCtrlAltDelClicked(); 52 | void onRepeatingKeystrokeChanged(int index); 53 | 54 | }; 55 | 56 | #endif // TOOLBARMANAGER_H -------------------------------------------------------------------------------- /ui/videopane.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifndef VIDEOPANE_H 24 | #define VIDEOPANE_H 25 | 26 | #include "target/mouseeventdto.h" 27 | #include "inputhandler.h" 28 | 29 | #include 30 | #include 31 | 32 | 33 | class VideoPane : public QVideoWidget 34 | { 35 | Q_OBJECT 36 | 37 | public: 38 | explicit VideoPane(QWidget *parent = nullptr); 39 | 40 | void showHostMouse(); 41 | void hideHostMouse(); 42 | void moveMouseToCenter(); 43 | void startEscTimer(); 44 | void stopEscTimer(); 45 | 46 | bool focusNextPrevChild(bool next) override; 47 | 48 | bool isRelativeModeEnabled() const { return relativeModeEnable; } 49 | void setRelativeModeEnabled(bool enable) { relativeModeEnable = enable; } 50 | 51 | private: 52 | int lastX=0; 53 | int lastY=0; 54 | bool relativeModeEnable; 55 | 56 | InputHandler *m_inputHandler; 57 | 58 | QTimer *escTimer; 59 | bool holdingEsc=false; 60 | 61 | MouseEventDTO* calculateRelativePosition(QMouseEvent *event); 62 | MouseEventDTO* calculateAbsolutePosition(QMouseEvent *event); 63 | MouseEventDTO* calculateMouseEventDto(QMouseEvent *event); 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /update_version.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import argparse 4 | from datetime import datetime 5 | 6 | def update_version(increase_version, increase_major, increase_minor): 7 | version_file_path = 'resources/version.h' 8 | 9 | # Check if the file exists 10 | if not os.path.exists(version_file_path): 11 | print(f"Error: {version_file_path} does not exist.") 12 | print("Current working directory:", os.getcwd()) 13 | print("Directory contents:", os.listdir()) 14 | exit(1) 15 | 16 | # Read current version from version.h 17 | with open(version_file_path, 'r') as f: 18 | version_content = f.read() 19 | version_match = re.search(r'#define APP_VERSION "([^"]+)"', version_content) 20 | if version_match: 21 | version = version_match.group(1) 22 | else: 23 | print(f"Error: Version not found in {version_file_path}") 24 | print("File contents:") 25 | print(version_content) 26 | exit(1) 27 | 28 | # Split version into parts 29 | try: 30 | major, minor, patch, days = version.split('.') 31 | except ValueError: 32 | print(f"Error: Invalid version format: {version}") 33 | exit(1) 34 | 35 | # Increment major or minor version if specified 36 | if increase_major: 37 | major = str(int(major) + 1) 38 | minor = '0' # Reset minor version 39 | patch = '0' # Reset patch version 40 | elif increase_minor: 41 | minor = str(int(minor) + 1) 42 | patch = '0' # Reset patch version 43 | 44 | # Increment patch version if specified 45 | if increase_version: 46 | patch = str(int(patch) + 1) 47 | 48 | # Calculate days from start of year 49 | current_date = datetime.now() 50 | days_from_start = (current_date - datetime(current_date.year, 1, 1)).days + 1 51 | days = str(days_from_start).zfill(3) # Ensure it's always 3 digits 52 | 53 | # Create new version string 54 | new_version = f"{major}.{minor}.{patch}.{days}" 55 | 56 | # Update version.h file 57 | new_version_content = re.sub( 58 | r'#define APP_VERSION "[^"]+"', 59 | f'#define APP_VERSION "{new_version}"', 60 | version_content 61 | ) 62 | with open(version_file_path, 'w') as f: 63 | f.write(new_version_content) 64 | 65 | print(f"Updated version to {new_version}") 66 | 67 | # Set environment variables for use in later steps 68 | with open(os.environ['GITHUB_ENV'], 'a') as env_file: 69 | env_file.write(f"NEW_VERSION={new_version}\n") 70 | env_file.write(f"VERSION_FOR_INNO={new_version}\n") 71 | 72 | if __name__ == "__main__": 73 | parser = argparse.ArgumentParser(description='Update the version in version.h') 74 | parser.add_argument('--increase-version', action='store_true', help='Increase the patch version number') 75 | parser.add_argument('--increase-major', action='store_true', help='Increase the major version number') 76 | parser.add_argument('--increase-minor', action='store_true', help='Increase the minor version number') 77 | args = parser.parse_args() 78 | 79 | update_version(args.increase_version, args.increase_major, args.increase_minor) 80 | 81 | -------------------------------------------------------------------------------- /usb/usb_win.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifdef _WIN32 24 | #include "usb_win.h" 25 | 26 | std::string ConvertWideToUTF8(const std::wstring& wstr) 27 | { 28 | std::wstring_convert, wchar_t> converter; 29 | return converter.to_bytes(wstr); 30 | } 31 | 32 | void GetUsbDevices() 33 | { 34 | HDEVINFO hDevInfo; 35 | SP_DEVINFO_DATA DeviceInfoData; 36 | DWORD i; 37 | 38 | // Create a HDEVINFO with all present devices 39 | hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 40 | if (hDevInfo == INVALID_HANDLE_VALUE) 41 | { 42 | // Insert error handling here 43 | return; 44 | } 45 | // Enumerate through all devices in the set 46 | DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 47 | for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) 48 | { 49 | DWORD DataT; 50 | LPTSTR buffer = NULL; 51 | DWORD buffersize = 0; 52 | 53 | while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, 54 | SPDRP_DEVICEDESC, &DataT, (PBYTE)buffer, buffersize, &buffersize)) 55 | { 56 | if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 57 | { 58 | // Change the buffer size 59 | if (buffer) LocalFree(buffer); 60 | buffer = (LPTSTR)LocalAlloc(LPTR, buffersize * 2); 61 | } 62 | else 63 | { 64 | // Insert error handling here 65 | break; 66 | } 67 | } 68 | 69 | std::wstring wDeviceName(buffer); 70 | std::string deviceName = ConvertWideToUTF8(wDeviceName); 71 | 72 | printf("Device: %s\n", deviceName.c_str()); 73 | 74 | if (buffer) LocalFree(buffer); 75 | } 76 | 77 | if (hDevInfo) SetupDiDestroyDeviceInfoList(hDevInfo); 78 | } 79 | #endif 80 | -------------------------------------------------------------------------------- /usb/usb_win.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ========================================================================== * 3 | * * 4 | * This file is part of the Openterface Mini KVM App QT version * 5 | * * 6 | * Copyright (C) 2024 * 7 | * * 8 | * This program is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation version 3. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, but * 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 15 | * General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | * ========================================================================== * 21 | */ 22 | 23 | #ifdef _WIN32 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #pragma comment(lib, "setupapi.lib") 35 | 36 | std::string ConvertWideToUTF8(const std::wstring& wstr); 37 | void GetUsbDevices(); 38 | 39 | #endif -------------------------------------------------------------------------------- /valgrind.supp: -------------------------------------------------------------------------------- 1 | { 2 | TLS related: tls_get_addr_tail 3 | Memcheck:Leak 4 | match-leak-kinds: possible 5 | fun:malloc 6 | ... 7 | fun:tls_get_addr_tail 8 | } 9 | 10 | { 11 | TLS related: update_tls_slotinfo 12 | Memcheck:Leak 13 | match-leak-kinds: possible 14 | fun:malloc 15 | ... 16 | fun:update_tls_slotinfo 17 | } 18 | 19 | { 20 | QApplicationPrivate::init private 21 | Memcheck:Leak 22 | match-leak-kinds: possible 23 | ... 24 | fun:_ZN22QGuiApplicationPrivate4initEv 25 | } 26 | 27 | { 28 | QApplicationPrivate::init private 29 | Memcheck:Param 30 | writev(vector[0]) 31 | ... 32 | fun:_ZN22QGuiApplicationPrivate4initEv 33 | } 34 | -------------------------------------------------------------------------------- /video/firmwarewriter.cpp: -------------------------------------------------------------------------------- 1 | #include "firmwarewriter.h" 2 | #include "videohid.h" 3 | 4 | #include 5 | #include 6 | 7 | FirmwareWriter::FirmwareWriter(VideoHid* videoHid, quint16 address, const QByteArray& firmware, QObject* parent) 8 | : QObject(parent), m_videoHid(videoHid), m_address(address), m_firmware(firmware) 9 | { 10 | } 11 | 12 | void FirmwareWriter::process() 13 | { 14 | qDebug() << "Starting firmware write process in thread:" << QThread::currentThreadId(); 15 | 16 | int totalSize = m_firmware.size(); 17 | int lastPercent = 0; 18 | 19 | // Connect to the VideoHid written_size signal to track progress 20 | connect(m_videoHid, &VideoHid::firmwareWriteChunkComplete, this, [this, totalSize, &lastPercent](int writtenBytes) { 21 | int percent = (writtenBytes * 100) / totalSize; 22 | if (percent > lastPercent) { 23 | lastPercent = percent; 24 | emit progress(percent); 25 | } 26 | }); 27 | 28 | // Perform the actual firmware write 29 | bool success = m_videoHid->writeEeprom(m_address, m_firmware); 30 | 31 | // Signal completion 32 | emit finished(success); 33 | } 34 | -------------------------------------------------------------------------------- /video/firmwarewriter.h: -------------------------------------------------------------------------------- 1 | #ifndef FIRMWAREWRITER_H 2 | #define FIRMWAREWRITER_H 3 | 4 | #include 5 | #include 6 | 7 | class VideoHid; 8 | 9 | class FirmwareWriter : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit FirmwareWriter(VideoHid* videoHid, quint16 address, const QByteArray& firmware, QObject* parent = nullptr); 15 | 16 | public slots: 17 | void process(); 18 | 19 | signals: 20 | void progress(int percent); 21 | void finished(bool success); 22 | 23 | private: 24 | VideoHid* m_videoHid; 25 | quint16 m_address; 26 | QByteArray m_firmware; 27 | }; 28 | 29 | #endif // FIRMWAREWRITER_H 30 | -------------------------------------------------------------------------------- /video/ms2109.h: -------------------------------------------------------------------------------- 1 | #ifndef MS2109_H 2 | #define MS2109_H 3 | 4 | #include 5 | #include 6 | 7 | const uint16_t ADDR_HDMI_CONNECTION_STATUS = 0xFA8C; 8 | // 0xDF00 bit0: GPIO0 reads the hard switch status, 1 means switchable usb connects to the target, 0 means switchable usb connects to the host 9 | const uint16_t ADDR_GPIO0 = 0xDF00; 10 | // 0xDF01 bit5: SPDIFOUT reads the soft switch status, 1 means switchable usb connects to the target, 0 means switchable usb connects to the host 11 | const uint16_t ADDR_SPDIFOUT = 0xDF01; 12 | 13 | const uint16_t ADDR_EEPROM = 0x0000; 14 | 15 | const uint16_t ADDR_FIRMWARE_VERSION_0 = 0xCBDC; 16 | const uint16_t ADDR_FIRMWARE_VERSION_1 = 0xCBDD; 17 | const uint16_t ADDR_FIRMWARE_VERSION_2 = 0xCBDE; 18 | const uint16_t ADDR_FIRMWARE_VERSION_3 = 0xCBDF; 19 | 20 | // The patch variable address for input width and height is not correct, so we need to use the correct address 21 | // const uint16_t ADDR_INPUT_WIDTH_H = 0xC738; //old address 22 | // const uint16_t ADDR_INPUT_WIDTH_L = 0xC739; //old address 23 | 24 | const uint16_t ADDR_INPUT_WIDTH_H = 0xC6AF; 25 | const uint16_t ADDR_INPUT_WIDTH_L = 0xC6B0; 26 | 27 | // const uint16_t ADDR_INPUT_HEIGHT_H = 0xC73A; //old address 28 | // const uint16_t ADDR_INPUT_HEIGHT_L = 0xC73B; //old address 29 | const uint16_t ADDR_INPUT_HEIGHT_H = 0xC6B1; 30 | const uint16_t ADDR_INPUT_HEIGHT_L = 0xC6B2; 31 | 32 | // const uint16_t ADDR_FPS_H = 0xC73E; 33 | // const uint16_t ADDR_FPS_L = 0xC73F; 34 | 35 | const uint16_t ADDR_INPUT_FPS_H = 0xC6B5; 36 | const uint16_t ADDR_INPUT_FPS_L = 0xC6B6; 37 | 38 | const uint16_t ADDR_INPUT_PIXELCLK_H = 0xC73C; 39 | const uint16_t ADDR_INPUT_PIXELCLK_L = 0xC73D; 40 | 41 | // const uint16_t ADDR_INPUT_PIXELCLK_H = 0xC6B3; 42 | // const uint16_t ADDR_INPUT_PIXELCLK_L = 0xC6B4; 43 | 44 | const quint8 CMD_XDATA_WRITE = 0xB6; 45 | const quint8 CMD_XDATA_READ = 0xB5; 46 | 47 | const quint8 CMD_EEPROM_WRITE = 0xE6; 48 | const quint8 CMD_EEPROM_READ = 0xE5; 49 | 50 | #endif // MS2109_H 51 | --------------------------------------------------------------------------------